Câu trả lời:
Một cách tiếp cận sẽ là thêm set -e
vào phần đầu của kịch bản của bạn. Điều đó có nghĩa là (từ help set
):
-e Exit immediately if a command exits with a non-zero status.
Vì vậy, nếu bất kỳ lệnh nào của bạn thất bại, tập lệnh sẽ thoát.
Ngoài ra, bạn có thể thêm các exit
tuyên bố rõ ràng tại các điểm thất bại có thể:
command || exit 1
set -e
là cách duy nhất tôi biết để làm điều đó.
set -e
là sleep
( break
được dựng sẵn đặc biệt sẽ khiến tập lệnh thoát khỏi lỗi trong hầu hết các shell, các lệnh trong if
hoặc bên trái &&
không bị ảnh hưởng set -e
, n=...
có thể thất bại nếu n
chỉ đọc, nhưng sau đó điều đó cũng sẽ thoát khỏi tập lệnh mà không có set -e
khả năng giải thích), do đó việc giải thích nghe có vẻ khó xảy ra. Tôi đồng ý câu hỏi là từ kém.
Bạn có thể thoát một tập lệnh tại bất kỳ nơi nào bằng cách sử dụng từ khóa exit
. Bạn cũng có thể chỉ định một mã thoát dùng để báo hiệu cho các chương trình khác mà hay như thế nào kịch bản của bạn thất bại, ví dụ exit 1
hoặc exit 2
vv (Theo quy ước, lối ra mã 0 là cho sự thành công và lớn hơn bất cứ điều gì hơn 0 biểu thị sự thất bại, tuy nhiên, cũng theo quy ước, xuất cảnh các mã trên 127 được dành riêng để chấm dứt bất thường (ví dụ: bằng tín hiệu)).
Cấu trúc chung để thoát khỏi thất bại là
if [ failure condition ]; then
exit n
fi
với phù hợp failure condition
và n
. Nhưng trong các kịch bản cụ thể, bạn có thể tiến hành khác nhau. Bây giờ đối với trường hợp của bạn, tôi giải thích câu hỏi của bạn rằng nếu bất kỳ một trong năm yêu cầu gksu
thất bại, thì bạn có nghĩa là để thoát. Một cách là sử dụng một chức năng như thế này
function try_command {
for i in 1 2 3 4 5 ; do
if gksu command ; then
return 0
fi
fi
exit 1
}
và sau đó, gọi vòng lặp bằng try_command
.
Có (nhiều hơn) các cách nâng cao hoặc tinh vi về cách giải quyết câu hỏi của bạn. Tuy nhiên, giải pháp ở trên dễ tiếp cận hơn với người mới bắt đầu hơn là, giải pháp của Stephane.
attempt=0
until gksu command; do
attempt=$((attempt + 1))
if [ "$attempt" -gt 5 ]; then
exit 1
fi
done
exit
thoát khỏi tập lệnh trừ khi nó được gọi trong một subshell. Nếu đó là một phần của kịch bản là trong một subshell, ví dụ vì nó trong (...)
hoặc $(...)
hoặc một phần của đường ống dẫn, sau đó nó sẽ chỉ thoát subshell đó .
Trong trường hợp đó, nếu bạn muốn tập lệnh thoát ra ngoài lớp con, thì bạn sẽ cần phải gọi exit
khi thoát khỏi lớp con đó.
Chẳng hạn, ở đây có 2 cấp độ con:
(
life=hard
output=$(
echo blah
[ "$life" = easy ] || exit 1 # exit subshell
echo blih not run
) || exit # if the subshell exits with a non-zero exit status,
# exit as well with the same exit status
echo not run either
) || exit # if the subshell exits with a non-zero exit status,
# exit as well with the same exit status
Nó có thể trở nên phức tạp hơn nếu lớp vỏ là một phần của đường ống. bash
có một đặc biệt $PIPESTATUS
mảng, tương tự như zsh
của $pipestatus
một có thể giúp bạn ở đây:
{
echo foo
exit 1
echo bar
} | wc -c
subshell_ret=${PIPESTATUS[0]}
if [ "$subshell_ret" -ne 0 ]; then
exit "$subshell_ret"
fi
Bẫy sẽ thực hiện một hành động khi nhận được tín hiệu.
trap "echo EXIT; exit" 0
trap "echo HUP; exit" 1
trap "echo CTL-C; exit" 2
trap "echo QUIT; exit" 3
trap "echo ERR; exit" ERR
n=0
until [ $n -ge 5 ]
do
n=$[$n+1]
echo $n
sleep 3
done
Chạy cái này và để nó thoát bình thường. Nó bẫy tín hiệu 0.
EXIT
Chạy lại và ngắt với ^ C. Nó bẫy cả tín hiệu 2 và tín hiệu 0.
CTL-C
EXIT
Trạng thái thoát không bằng 0 sẽ bẫy trên ERR
ERR
EXIT
set -e
. Nó không thực sự áp dụng ở đây mặc dù. OP muốn thoát khỏi tập lệnh sau 5 lần thất bại để chạy lệnh.