Zuvor wurde die Antwort mit dem jetzt ersten Abschnitt als letztem Abschnitt präsentiert.
Die POSIX-Shell enthält einen !
Operator
Beim Stöbern in der Shell-Spezifikation für andere Probleme habe ich kürzlich (September 2015) festgestellt, dass die POSIX-Shell einen !
Operator unterstützt . Beispielsweise wird es als reserviertes Wort aufgeführt und kann am Anfang einer Pipeline angezeigt werden - wobei ein einfacher Befehl ein Sonderfall von 'Pipeline' ist. Es kann daher auch in if
Anweisungen und / while
oder until
Schleifen verwendet werden - in POSIX-kompatiblen Shells. Folglich ist es trotz meiner Vorbehalte wahrscheinlich weiter verbreitet als ich 2008 festgestellt habe. Eine kurze Überprüfung von POSIX 2004 und SUS / POSIX 1997 zeigt, dass !
es in beiden Versionen vorhanden war.
Beachten Sie, dass der !
Operator am Anfang der Pipeline erscheinen muss und den Statuscode der gesamten Pipeline negiert (dh den letzten Befehl). Hier sind einige Beispiele.
$ ! 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
Tragbare Antwort - funktioniert mit antiken Muscheln
In einem Bourne-Skript (Korn, POSIX, Bash) verwende ich:
if ...command and arguments...
then : it succeeded
else : it failed
fi
Dies ist so portabel wie es nur geht. Der 'Befehl und die Argumente' können eine Pipeline oder eine andere zusammengesetzte Folge von Befehlen sein.
Ein not
Befehl
Das '!' Der in Ihre Shell integrierte oder von den Betriebssystemen bereitgestellte Operator ist nicht allgemein verfügbar. Es ist jedoch nicht besonders schwer zu schreiben - der folgende Code stammt mindestens aus dem Jahr 1991 (obwohl ich glaube, dass ich vor einiger Zeit eine frühere Version geschrieben habe). Ich verwende dies jedoch nicht in meinen Skripten, da es nicht zuverlässig verfügbar ist.
/*
@(
@(
@(
@(
@(
@(
*/
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);
}
Dies gibt 'Erfolg' zurück, das Gegenteil von Fehler, wenn der Befehl nicht ausgeführt werden kann. Wir können darüber diskutieren, ob die Option "Nichts erfolgreich machen" richtig war. Vielleicht sollte es einen Fehler melden, wenn es nicht aufgefordert wird, etwas zu tun. Der Code in ' "stderr.h"
' bietet einfache Funktionen zur Fehlerberichterstattung - ich verwende ihn überall. Quellcode auf Anfrage - siehe meine Profilseite, um mich zu kontaktieren.