Làm thế nào tôi có thể làm một cái gì đó như thế này trong bash?
if "`command` returns any error";
then
echo "Returned an error"
else
echo "Proceed..."
fi
Làm thế nào tôi có thể làm một cái gì đó như thế này trong bash?
if "`command` returns any error";
then
echo "Returned an error"
else
echo "Proceed..."
fi
Câu trả lời:
Làm thế nào để có điều kiện làm một cái gì đó nếu một lệnh thành công hoặc thất bại
Đó chính xác là những gì if
tuyên bố của bash :
if command ; then
echo "Command succeeded"
else
echo "Command failed"
fi
Thêm thông tin từ các bình luận: bạn không cần sử dụng cú pháp [
... ]
trong trường hợp này. [
bản thân nó là một lệnh, rất gần tương đương với test
. Đây có lẽ là lệnh phổ biến nhất để sử dụng trong một if
, điều này có thể dẫn đến giả định rằng đó là một phần của cú pháp của shell. Nhưng nếu bạn muốn kiểm tra xem một lệnh có thành công hay không, hãy sử dụng chính lệnh đó if
, như được hiển thị ở trên.
Chỉnh sửa: Trích dẫn câu hỏi ở đầu trang cho rõ ràng (câu trả lời này không xuất hiện gần đầu trang).
then
trên một dòng riêng biệt.
if ! command ; then ... ; fi
. [
bản thân nó là một lệnh và nó không cần thiết trong trường hợp này.
if [ ! command ]
không thực hiện command
; nó coi command
như một chuỗi và coi nó là đúng vì nó có độ dài khác không. [
là một từ đồng nghĩa với test
lệnh
Đối với những điều nhỏ mà bạn muốn xảy ra nếu lệnh shell hoạt động, bạn có thể sử dụng &&
cấu trúc:
rm -rf somedir && trace_output "Removed the directory"
Tương tự như vậy đối với những điều nhỏ mà bạn muốn xảy ra khi lệnh shell bị lỗi, bạn có thể sử dụng ||
:
rm -rf somedir || exit_on_error "Failed to remove the directory"
Hoặc cả hai
rm -rf somedir && trace_output "Removed the directory" || exit_on_error "Failed to remove the directory"
Có thể không khôn ngoan khi làm rất nhiều với các cấu trúc này, nhưng đôi khi chúng có thể làm cho dòng kiểm soát rõ ràng hơn rất nhiều.
Kiểm tra giá trị của $?
, trong đó có kết quả thực hiện lệnh / hàm gần đây nhất:
#!/bin/bash
echo "this will work"
RESULT=$?
if [ $RESULT -eq 0 ]; then
echo success
else
echo failed
fi
if [ $RESULT == 0 ]; then
echo success 2
else
echo failed 2
fi
if
thành ngữ của Bash . Tôi thích câu trả lời của Keith Thompson.
if
là để làm điều này. Các điều kiện kiểm soát dòng chảy trong Bash tất cả kiểm tra $?
đằng sau hậu trường; đó là những gì họ làm. Rõ ràng kiểm tra giá trị của nó là không cần thiết trong phần lớn các trường hợp, và thường là một antipotype mới bắt đầu.
if ! cmd
thì tốt thôi. Mặt khác, một sự sắp xếp phổ biến là sử dụng một else
mệnh đề. Bạn không thể có một sản phẩm nào then
nhưng đôi khi bạn thấy then : nothing; else
nơi :
không có ý nghĩa. true
cũng sẽ làm việc ở đó
Điều này làm việc cho tôi:
command && echo "OK" || echo "NOK"
nếu command
thành công, thì echo "OK"
được thực thi và vì nó thành công, nên việc thực thi dừng ở đó. Mặt khác, &&
được bỏ qua, và echo "NOK"
được thực thi.
command && echo "OK" || c=$?; echo "NOK"; $(exit $c)
command && echo "OK" || (c=$?; echo "NOK"; (exit $c))
vậy?
echo "OK"
phận có thể tự thất bại, thì điều này tốt hơn:command && (echo "OK"; exit 0) || (c=$?; echo "NOK"; (exit $c))
Cần lưu ý rằng if...then...fi
và &&
/ ||
loại giao dịch tiếp cận với trạng thái thoát được trả về bằng lệnh chúng tôi muốn kiểm tra (0 khi thành công); tuy nhiên, một số lệnh không trả về trạng thái thoát khác không nếu lệnh không thành công hoặc không thể xử lý đầu vào. Điều này có nghĩa là các cách tiếp cận thông thường if
và &&
/ ||
sẽ không hoạt động đối với các lệnh cụ thể đó.
Chẳng hạn, trên Linux GNU file
vẫn tồn tại với 0 nếu nó nhận được tệp không tồn tại dưới dạng đối số và find
không thể xác định vị trí người dùng tệp được chỉ định.
$ find . -name "not_existing_file"
$ echo $?
0
$ file ./not_existing_file
./not_existing_file: cannot open `./not_existing_file' (No such file or directory)
$ echo $?
0
Trong các trường hợp như vậy, một cách tiềm năng mà chúng ta có thể xử lý tình huống là bằng cách đọc stderr
/ stdin
tin nhắn, ví dụ: những cách được trả về bằng file
lệnh hoặc phân tích đầu ra của lệnh như trong find
. Đối với mục đích đó, case
tuyên bố có thể được sử dụng.
$ file ./doesntexist | while IFS= read -r output; do
> case "$output" in
> *"No such file or directory"*) printf "%s\n" "This will show up if failed";;
> *) printf "%s\n" "This will show up if succeeded" ;;
> esac
> done
This will show up if failed
$ find . -name "doesn'texist" | if ! read IFS= out; then echo "File not found"; fi
File not found
Lỗi dễ mắc nhất mà tôi có thể gặp phải là:
RR=$?
Bây giờ, không chỉ đối với tình huống này, mà cả những vấn đề khác mà bạn có thể gặp phải, hãy xem xét:
$ AA=1 ; if (( "10#0${AA}" == 1 )) ; then echo yes ; else echo no ; fi
Trả lời có
$ AA=1 ; if (( "10#0${AA}" != 1 )) ; then echo yes ; else echo no ; fi
Trả lời: không
$ AA=1 ; if (( "10#0${BB}" == 1 )) ; then echo yes ; else echo no ; fi
Trả lời: không
$ AA=1 ; if (( "10#0${BB}" != 1 )) ; then echo yes ; else echo no ; fi
Trả lời có
$ AA=1 ; if (( "10#0${BB}" == 0 )) ; then echo yes ; else echo no ; fi
Trả lời có
Điều này ngăn chặn tất cả các loại lỗi.
Bạn có thể nhận thức được tất cả các cú pháp, nhưng ở đây một số mẹo:
"blank"
để được nothing
.${variable}
.base-8
. Bạn sẽ gặp một lỗi như:
value too great for base (error token is "08")
cho các số trên 7
. Đó là khi 10#
đi vào chơi:10#
buộc số lượng được base-10
.Bạn có thể làm được việc này:
if ($( ping 4.4.4.4 -c1 > /dev/null )) ; then
echo "ping response succsess!!!"
fi
ping
được ghi lại để xem chạy nó dưới dạng một lệnh. Nhưng vì đầu ra được chuyển hướng đến / dev / null nên sẽ luôn là chuỗi rỗng. Vì vậy, bạn không chạy gì trong một lớp con, có nghĩa là trạng thái thoát trước đó (của lớp con thay thế lệnh, đó là ping) sẽ được giữ lại. Rõ ràng, cách chính xác là if ping ...; then
ở đây.
Như đã lưu ý ở nơi khác trong chủ đề này, câu hỏi ban đầu về cơ bản tự trả lời. Dưới đây là một minh họa cho thấy các if
điều kiện cũng có thể được lồng nhau.
Ví dụ này sử dụng if
để kiểm tra nếu một tệp tồn tại và nếu đó là một tệp thông thường. Nếu những điều kiện đó là đúng, thì hãy kiểm tra xem nó có kích thước lớn hơn 0 hay không.
#!/bin/bash
echo "Which error log are you checking today? "
read answer
if [ -f /opt/logs/$answer*.errors ]
then
if [ -s /opt/logs/$answer*.errors ]
then
echo "Content is present in the $answer error log file."
else
echo "No errors are present in the $answer error log file."
fi
else
echo "$answer does not have an error log at this time."
fi
#!/bin/bash
if command-1 ; then
echo "command-1 succeeded and now running from this block command-2"
command-2
else
echo "command-1 failed and now running from this block command-3"
command-3
fi
Điều này có thể được thực hiện đơn giản theo cách này vì $?
cung cấp cho bạn trạng thái của lệnh cuối cùng được thực thi.
Vì vậy, nó có thể là
#!/bin/sh
... some command ...
if [ $? == 0 ] ; then
echo '<the output message you want to display>'
else
echo '<failure message>'
fi