Câu trả lời:
Một cách tiếp cận sẽ là thêm set -evà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 exittuyên bố rõ ràng tại các điểm thất bại có thể:
command || exit 1
set -elà cách duy nhất tôi biết để làm điều đó.
set -elà 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 ifhoặc bên trái &&không bị ảnh hưởng set -e, n=...có thể thất bại nếu nchỉ đọc, nhưng sau đó điều đó cũng sẽ thoát khỏi tập lệnh mà không có set -ekhả 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 1hoặc exit 2vv (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 conditionvà 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 gksuthấ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
exitthoá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 exitkhi 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. bashcó một đặc biệt $PIPESTATUSmảng, tương tự như zshcủa $pipestatusmộ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.