ก่อนหน้านี้มีการนำเสนอคำตอบว่าตอนนี้ส่วนแรกเป็นส่วนสุดท้ายคืออะไร
POSIX Shell มีตัว!
ดำเนินการ
เมื่อมองไปรอบ ๆ ข้อกำหนดของเชลล์สำหรับปัญหาอื่น ๆ ฉันเพิ่งสังเกตเห็นว่า POSIX เชลล์รองรับตัว!
ดำเนินการ ตัวอย่างเช่นแสดงเป็นคำสงวนและสามารถปรากฏที่จุดเริ่มต้นของไปป์ไลน์โดยที่คำสั่งธรรมดาเป็นกรณีพิเศษของ 'ไปป์ไลน์' ดังนั้นจึงสามารถใช้ในif
คำสั่งและwhile
หรือuntil
วนซ้ำได้เช่นกัน - ในเชลล์ที่สอดคล้องกับ POSIX ดังนั้นแม้จะมีการจองของฉัน แต่ก็น่าจะมีให้บริการในวงกว้างมากกว่าที่ฉันรู้ในปี 2008 การตรวจสอบ POSIX 2004 และ SUS / POSIX 1997 อย่างรวดเร็วแสดงให้เห็นว่า!
มีอยู่ในทั้งสองเวอร์ชัน
โปรดสังเกตว่าตัว!
ดำเนินการต้องปรากฏที่จุดเริ่มต้นของไปป์ไลน์และลบล้างรหัสสถานะของไปป์ไลน์ทั้งหมด (เช่นคำสั่งสุดท้าย ) นี่คือตัวอย่างบางส่วน.
$ ! 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
คำตอบแบบพกพา - ใช้ได้กับเปลือกหอยโบราณ
ในสคริปต์ Bourne (Korn, POSIX, Bash) ฉันใช้:
if ...command and arguments...
then : it succeeded
else : it failed
fi
นี่คือแบบพกพาที่ได้รับ 'คำสั่งและอาร์กิวเมนต์' อาจเป็นไปป์ไลน์หรือลำดับประกอบอื่น ๆ ของคำสั่ง
not
คำสั่ง
'!' ตัวดำเนินการไม่ว่าจะติดตั้งในเชลล์ของคุณหรือที่จัดเตรียมโดย o / s จะไม่สามารถใช้งานได้ แม้ว่าจะไม่ยากที่จะเขียน แต่โค้ดด้านล่างนี้มีอายุย้อนกลับไปอย่างน้อยปี 1991 (แม้ว่าฉันคิดว่าฉันเขียนเวอร์ชันก่อนหน้านานกว่านั้น) ฉันไม่มักจะใช้สิ่งนี้ในสคริปต์ของฉันเพราะมันไม่สามารถใช้ได้อย่างน่าเชื่อถือ
/*
@(
@(
@(
@(
@(
@(
*/
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);
}
สิ่งนี้จะส่งคืน 'ความสำเร็จ' ตรงข้ามกับความล้มเหลวเมื่อไม่สามารถดำเนินการคำสั่งได้ เราสามารถถกเถียงกันได้ว่าตัวเลือก "ไม่ทำอะไรสำเร็จ" นั้นถูกต้องหรือไม่ บางทีควรรายงานข้อผิดพลาดเมื่อไม่ได้ขอให้ทำอะไรเลย รหัสใน ' "stderr.h"
' มีสิ่งอำนวยความสะดวกในการรายงานข้อผิดพลาดอย่างง่าย - ฉันใช้ทุกที่ ซอร์สโค้ดตามคำขอ - ดูหน้าโปรไฟล์ของฉันเพื่อติดต่อฉัน