Anteriormente, la respuesta se presentaba con lo que ahora es la primera sección como la última sección.
POSIX Shell incluye un !
operador
Al hurgar en la especificación del shell por otros problemas, recientemente (septiembre de 2015) noté que el shell POSIX admite un !
operador. Por ejemplo, aparece como una palabra reservada y puede aparecer al comienzo de una canalización , donde un comando simple es un caso especial de 'canalización'. Por lo tanto, también se puede usar en if
declaraciones while
o until
bucles, en shells compatibles con POSIX. En consecuencia, a pesar de mis reservas, probablemente esté más disponible de lo que me di cuenta en 2008. Una revisión rápida de POSIX 2004 y SUS / POSIX 1997 muestra que !
estaba presente en ambas versiones.
Tenga en cuenta que el !
operador debe aparecer al comienzo de la tubería y niega el código de estado de toda la tubería (es decir, el último comando). Aquí hay unos ejemplos.
$ ! 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
Respuesta portátil: funciona con conchas antiguas
En un script de Bourne (Korn, POSIX, Bash), uso:
if ...command and arguments...
then : it succeeded
else : it failed
fi
Esto es lo más portátil posible. El 'comando y argumentos' puede ser una canalización u otra secuencia compuesta de comandos.
Un not
comando
Los '!' El operador, ya sea integrado en su shell o proporcionado por el o / s, no está disponible universalmente. Sin embargo, no es terriblemente difícil de escribir: el código a continuación se remonta al menos a 1991 (aunque creo que escribí una versión anterior incluso hace más tiempo). Sin embargo, no suelo usar esto en mis scripts porque no está disponible de manera confiable.
/*
@(
@(
@(
@(
@(
@(
*/
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);
}
Esto devuelve "éxito", lo opuesto al fracaso, cuando no se ejecuta el comando. Podemos debatir si la opción "no hacer nada con éxito" era correcta; tal vez debería informar un error cuando no se le pide que haga nada. El código en " "stderr.h"
" proporciona funciones sencillas de notificación de errores; lo uso en todas partes. Código fuente a pedido - vea mi página de perfil para contactarme.