Chờ sử dụng lệnh trong Linux?


16
#!/bin/bash
function back()
{
    sleep $1
    exit $2
}
back $1 $2 &
b=$!
if `wait $!`;then
    echo success
else
    echo failure
fi
bash-3.00# ./back 300 0
failure
bash-3.00# ./back 300 1
failure

Tôi đã mong đợi successnhư trạng thái thoát khi tôi gửi 0, nhưng tôi vẫn nhận được failure.

Ngoài ra, waitkhông chờ 300 giây. Thay vào đó, tôi nhận được tin nhắn ngay lập tức. Tôi giả sử $!là con ngay lập tức $$trong kịch bản của tôi. Phải không?

Có thể chụp trạng thái thoát của chờ đợi như thế exit_status=$(wait $!)nào?

if ! ((exit_status));then
    echo sucess
else
    failure
fi

Câu trả lời:


20

Vấn đề là bạn đang phát hành waittrong một subshell:

if `wait $!`;then

Bởi vì waitlà một nội trang, không phải là một lệnh, nó hoạt động trên lớp con , không phải vỏ hiện tại của bạn.

Đầu ra mà bạn sẽ thấy nhưng không phải là:

wait: pid 12344 is not a child of this shell

... với trạng thái trả về là 1.

Để thực hiện bài kiểm tra của bạn, bạn sẽ cần phải làm điều đó mà không cần sử dụng một lớp con.

#!/bin/bash
function back()
{
  sleep $1
  exit $2
}
back $1 $2 &
b=$!

wait $b && echo success || echo failure

Điều này mang lại kết quả mà bạn mong đợi và chờ đợi miễn là bạn mong đợi:

$ time ./test.sh 3 0
success
./test.sh 3 0  0.00s user 0.01s system 0% cpu 3.012 total
$ time ./test.sh 3 1
failure
./test.sh 3 1  0.00s user 0.01s system 0% cpu 3.012 total

Bạn có thể kiểm tra trạng thái thoát của bất kỳ lệnh nào bằng $?:

$ /bin/true
$ echo $?
0
$ /bin/false
$ echo $?
1

Có một vài lỗi khác trong kịch bản của bạn. #!Dòng của bạn không đúng, mà tôi đã sửa. Bạn gán $!cho $b, nhưng không sử dụng $b.


12

Loại bỏ các backticks.

Như là, bạn đang thực hiện waittrong một subshell, không có quyền truy cập vào các công việc của shell cha, vì vậy nó sẽ ngay lập tức thất bại.


Nếu bạn muốn trạng thái thoát, nhận giá trị $?ngay sau khi chờ.

command_here &
wait
status=$?

2

Loại bỏ các backticks sẽ làm cho chương trình hoạt động, nhưng không hoàn toàn vì những lý do đã được xác định. Đúng là waitkhông thành công ngay lập tức vì nó chạy trong một lớp con và không thể truy cập vào các tiến trình của cha mẹ, nhưng chương trình sẽ không chạy như mong đợi ngay cả khi bạn sử dụng một lệnh đã hoạt động.

Câu iflệnh chạy một chương trình và kiểm tra xem trạng thái thoát của nó là 0 hay không. Khi bạn sử dụng backticks, câu lệnh if sẽ lấy đầu ra của tiến trình, cố gắng chạy nó dưới dạng chương trình và sau đó sử dụng mã thoát cho quy trình đó. Vì vậy, chương trình không thất bại vì waitthất bại, mà là thất bại vì waitkhông tạo ra bất kỳ đầu ra nào.

Bạn có thể làm cho tập lệnh hoạt động bằng cách sử dụng echobên trong backticks:

if `echo wait $!`; then
    echo success
else
    echo failure
fi

Hoặc chỉ cần loại bỏ các backticks; dễ dàng hơn cho mọi người

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.