Câu hỏi Làm thế nào để kiểm tra xem một lệnh đã thành công?


Có cách nào để kiểm tra xem có lỗi trong khi thực thi lệnh không?

Thí dụ :

test1=`sed -i "/:@/c connection.url=jdbc:oracle:thin:@$ip:1521:$dataBase" $search`
valid $test1

function valid () {
  if $test -eq 1; then
    echo "OK"
    else echo "ERROR" 
  fi
}

Tôi đã thử làm điều đó nhưng có vẻ như nó không hoạt động. Tôi không làm thế.


162
2018-03-07 11:40


gốc


Thích hơn $ (foo) hơn backticks `foo`, bởi vì bạn có thể lồng nó và dễ phân biệt hơn với các dấu nháy đơn. - user unknown
BTW, bạn cần định nghĩa một hàm (valid) trước khi bạn gọi nó. - wjandrea


Các câu trả lời:


Giá trị trả về được lưu trữ trong $?. 0 cho biết thành công, số khác chỉ ra lỗi.

some_command
if [ $? -eq 0 ]; then
    echo OK
else
    echo FAIL
fi

Giống như bất kỳ giá trị văn bản nào khác, bạn có thể lưu trữ nó trong một biến để so sánh trong tương lai:

some_command
retval=$?
do_something $retval
if [ $retval -ne 0 ]; then
    echo "Return code was not zero but $retval"
fi

Đối với các toán tử so sánh có thể, hãy xem man test.


240
2018-03-07 12:06



Đó là tốt đẹp ... tôi có thể giữ lỗi đầu ra ?? !! , bởi vì trong trường hợp này tôi có 2 lỗi: lệnh lỗi "văn bản" cũ, tập tin không tìm thấy và lỗi của tôi "văn bản" nào là trong trường hợp này không thành công ví dụ - moata_u
@moata_u: bạn có thể lưu trữ giá trị trong một biến như được hiển thị trong câu trả lời của tôi. - Lekensteyn
@moata_u: Bạn cần phải đặt ; trước else và fi: `if ...; sau đó ...; khác ...; fi - Lekensteyn
Đây là một sử dụng vô dụng test. - David Foerster
@Blauhirn [ $? ] (hoặc tương đương, test $?) không hoạt động vì $? đánh giá đến một số (0, 1, v.v.) không phải là số không. Xem tài liệu cho test: "Nếu EXPRESSION bị bỏ qua, 'test' trả về false. Nếu EXPRESSION là một đối số duy nhất, 'test' sẽ trả về false nếu đối số là null và true." - Lekensteyn


Nếu bạn chỉ cần biết nếu lệnh thành công hay thất bại, đừng bận tâm kiểm tra $?, chỉ cần kiểm tra lệnh trực tiếp. Ví dụ.:

if some_command; then
    printf 'some_command succeeded\n'
else
    printf 'some_command failed\n'
fi

Và gán đầu ra cho một biến không thay đổi giá trị trả về (tốt, trừ khi nó hoạt động khác nhau khi stdout không phải là một thiết bị đầu cuối của khóa học).

if output=$(some_command); then
    printf 'some_command succeded, the output was «%s»\n' "$output"
fi

http://mywiki.wooledge.org/BashGuide/TestsAndConditionals giải thích if chi tiết hơn.


60
2018-03-08 23:54



Điều gì sẽ xảy ra nếu bạn muốn làm điều gì khác hơn là phân nhánh như lưu trữ boolean cho dù nó không thành công hay không thành một .ini? Sau đó, biến đầu ra của bạn không làm điều đó, nhưng $? không, vì vậy bạn không chính xác trong việc nói rằng kiểm tra lệnh trực tiếp là hoàn toàn tốt hơn. - Timothy Swan


command && echo OK || echo Failed

19
2017-12-01 21:19



Nếu command trả về lỗi trên màn hình, làm thế nào để ẩn nó? - Sigur
Nếu command viết lỗi ra cho stderr, bạn có thể sử dụng biểu mẫu command 2> /dev/null && echo OK || echo Failed. Các 2> /dev/null chuyển hướng đầu ra stderr sang /dev/null. Tuy nhiên, một số tiện ích sẽ viết lỗi để stdout (mặc dù đây là thực hành không tốt). Trong trường hợp này, bạn có thể bỏ qua 2 từ chuyển hướng, nhưng bạn sẽ mất bất kỳ đầu ra nào từ lệnh. Phương pháp kiểm tra thành công này là tốt cho logic ternary đơn giản nhưng đối với hành vi phức tạp hơn, tốt nhất là kiểm tra $? cho lệnh thành công hoặc sử dụng lệnh if phương pháp chặn được nêu trong câu trả lời của @ geirha. - Bender the Greatest


$? nên chứa trạng thái thoát của lệnh trước đó, sẽ là 0 vì không có lỗi.

Vì vậy, một cái gì đó như;

cd /nonexistant
if [ $? -ne 0 ]
then
    echo failed
else
    echo success!
fi

đối với hầu hết các trường hợp, việc sử dụng lệnh && xây dựng chuỗi lệnh cần phải phụ thuộc vào nhau dễ dàng hơn. Vì thế cd /nonexistant && echo success! sẽ không phải echo thành công vì lệnh ngắt trước &&. Hệ quả của điều này là ||, ở đâu cd /nonexistant || echo fail  sẽ echo thất bại vì cd thất bại. (điều này trở nên hữu ích nếu bạn sử dụng một cái gì đó như || thoát, mà sẽ kết thúc kịch bản nếu lệnh trước thất bại.)


12
2018-03-07 12:04



Đó là tốt đẹp ... tôi có thể giữ lỗi đầu ra ?? !! , bởi vì trong trường hợp này tôi có 2 lỗi: lệnh lỗi "văn bản" cũ, tập tin không tìm thấy và lỗi của tôi "văn bản" nào là trong trường hợp này không thành công ví dụ - moata_u
@moata_u, xem mywiki.wooledge.org/BashFAQ/002 - geirha


command && echo $? || echo $?

4
2017-08-12 16:01





Dành cho kiểm tra lỗi lệnh của bạn:

execute [INVOKING-FUNCTION] [COMMAND]

execute () {
    error=$($2 2>&1 >/dev/null)

    if [ $? -ne 0 ]; then
        echo "$1: $error"
        exit 1
    fi
}

Lấy cảm hứng trong sản xuất Lean:


2
2017-12-29 04:20





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 mà 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ả lại trạng thái thoát khác nếu lệnh không thành công hoặc không thể xử lý được đầu vào. Điều này có nghĩa là thông thường if và &&/|| các phương pháp tiếp cận sẽ không hoạt động đối với các lệnh cụ thể đó.

Ví dụ, trên Linux GNU file vẫn thoát với 0 nếu nó nhận được một tập tin không tồn tại làm đối số và find không thể định vị 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 những trường hợp như vậy, một cách tiềm năng mà chúng tôi có thể xử lý tình huống là bằng cách đọc stderr/stdin tin nhắn, ví dụ: những người được trả lại bởi file lệnh hoặc phân tích cú pháp đầu ra của lệnh như trong find. Vì 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

(Đây là một repost của câu trả lời của riêng tôi trên câu hỏi liên quan tại unix.stackexchange.com )


0
2017-11-13 18:58





Như đã đề cập trong nhiều câu trả lời khác, một thử nghiệm đơn giản về $? sẽ làm, như thế này

if [ $? -eq 0 ]; then something; fi

Nếu bạn muốn kiểm tra nếu lệnh thất bại, bạn có thể sử dụng phiên bản ngắn hơn trong bash (nhưng có lẽ quá mức cần thiết) như sau:

if (($?)); then something; fi

Điều này hoạt động bằng cách sử dụng (( )) chế độ số học, vì vậy nếu lệnh được trả về success, I E. $? = 0 sau đó kiểm tra đánh giá ((0)) kiểm tra như false, nếu không nó sẽ trở lại true.

Để kiểm tra sự thành công, bạn đã có thể sử dụng:

if ! (($?)); then something; fi

nhưng nó không ngắn hơn nhiều so với ví dụ đầu tiên.


0
2017-08-16 21:07