Trước đây, câu trả lời đã được trình bày với những gì bây giờ là phần đầu tiên là phần cuối cùng.
POSIX Shell bao gồm một !
toán tử
Xem xét đặc điểm kỹ thuật shell cho các vấn đề khác, gần đây tôi (tháng 9 năm 2015) nhận thấy rằng shell POSIX hỗ trợ một !
toán tử. Ví dụ, nó được liệt kê là một từ dành riêng và có thể xuất hiện ở đầu một đường dẫn - trong đó một lệnh đơn giản là một trường hợp đặc biệt của 'đường ống'. Do đó, nó có thể được sử dụng trong các if
câu lệnh và while
hoặc until
các vòng lặp - trong các shell tuân thủ POSIX. Do đó, bất chấp sự dè dặt của tôi, nó có lẽ được phổ biến rộng rãi hơn so với những gì tôi nhận ra vào năm 2008. Kiểm tra nhanh POSIX 2004 và SUS / POSIX 1997 cho thấy nó !
có mặt trong cả hai phiên bản đó.
Lưu ý rằng !
toán tử phải xuất hiện ở đầu đường ống và phủ định mã trạng thái của toàn bộ đường ống (tức là lệnh cuối cùng ). Đây là một số ví dụ.
$ ! some-command succeed; echo $?
1
$ ! some-command fail | some-other-command fail; echo $?
0
$ ! some-command < succeed.txt; echo $?
1
$ ! RESULT=fail some-command; echo $?
0
$ if ! some-command < input.txt | grep Success > /dev/null; then echo 'Failure!'; recover-command; mv input.txt input-failed.txt; fi
Failure!
$ ls *.txt
input-failed.txt
Câu trả lời di động - hoạt động với vỏ cổ
Trong tập lệnh Bourne (Korn, POSIX, Bash), tôi sử dụng:
if ...command and arguments...
then : it succeeded
else : it failed
fi
Điều này là di động như nó được. 'Lệnh và các đối số' có thể là một đường ống dẫn hoặc chuỗi lệnh phức hợp khác.
Một not
lệnh
Các '!' nhà điều hành, cho dù được tích hợp sẵn trong trình bao của bạn hay được cung cấp bởi o / s, đều không khả dụng trên toàn cầu. Tuy nhiên, nó không quá khó để viết - đoạn mã dưới đây có từ ít nhất là năm 1991 (mặc dù tôi nghĩ rằng tôi đã viết một phiên bản trước đó thậm chí lâu hơn). Tuy nhiên, tôi không có xu hướng sử dụng điều này trong các tập lệnh của mình, vì nó không có sẵn một cách đáng tin cậy.
/*
@(
@(
@(
@(
@(
@(
*/
static const char sccs[] = "@(#)$Id: not.c,v 4.2 2005/06/22 19:44:07 jleffler Exp $";
int main(int argc, char **argv)
{
int pid;
int corpse;
int status;
err_setarg0(argv[0]);
if (argc <= 1)
{
/* Nothing to execute. Nothing executed successfully. */
/* Inverted exit condition is non-zero */
exit(1);
}
if ((pid = fork()) < 0)
err_syserr("failed to fork\n");
if (pid == 0)
{
/* Child: execute command using PATH etc. */
execvp(argv[1], &argv[1]);
err_syserr("failed to execute command %s\n", argv[1]);
/* NOTREACHED */
}
/* Parent */
while ((corpse = wait(&status)) > 0)
{
if (corpse == pid)
{
/* Status contains exit status of child. */
/* If exit status of child is zero, it succeeded, and we should
exit with a non-zero status */
/* If exit status of child is non-zero, if failed and we should
exit with zero status */
exit(status == 0);
/* NOTREACHED */
}
}
/* Failed to receive notification of child's death -- assume it failed */
return (0);
}
Điều này trả về 'thành công', ngược lại với thất bại, khi nó không thực hiện được lệnh. Chúng ta có thể tranh luận về việc liệu tùy chọn 'không làm gì thành công' có đúng không; có thể nó sẽ báo lỗi khi nó không được yêu cầu làm bất cứ điều gì. Mã trong ' "stderr.h"
' cung cấp các phương tiện báo cáo lỗi đơn giản - tôi sử dụng nó ở mọi nơi. Mã nguồn theo yêu cầu - xem trang hồ sơ của tôi để liên hệ với tôi.