Tengo un script bash con lo siguiente:
#!/bin/bash -e egrep "^username" /etc/passwd >/dev/null if[ $? -eq 0 ] then echo "doesn"t exist" fi
Este script no ejecutar sin la -e. ¿Qué hace -e
para este script? Además, ¿qué hace $?
en este contexto?
Comentarios
Responder
Su publicación en realidad contiene 2 preguntas.
-
La bandera
-e
indica al script que salga en caso de error. Más indicadoresSi hay un error, saldrá de inmediato.
-
$?
es el estado de salida del último comando. En Linux, un estado de salida de0
significa que el comando fue exitoso. Cualquier otro estado significaría que se produjo un error.
Para aplicar estas respuestas a su script:
egrep "^username" /etc/passwd >/dev/null
buscaría el username
en el archivo /etc/passwd
.
-
Si lo encuentra entonces el estado de salida
$?
será igual a0
. -
Si no «Si no lo encuentra, el estado de salida será otro (no
0
). Aquí, querrá ejecutar laecho "doesn"t exist"
parte del código.
Desafortunadamente hay un error en su script, y ejecutarías ese código si el usuario existe – cambia la línea a
if [ $? -ne 0 ]
para tener la lógica correcta.
Sin embargo si el usuario no «t existe, egrep
devolverá un error c oda, y debido a la opción -e
, el shell saldrá inmediatamente después de esa línea, por lo que nunca llegará a esa parte del código.
Comentarios
- Además, puede hacer que el script funcione correctamente sin la -e reemplazando las dos primeras líneas con
if egrep "^username" /etc/passwd >/dev/null
. - Sin embargo, ¿por qué no se requiere
set
? : – / - @pst: Porque el
-e
se le da a bash como un argumento de línea de comando. Todas las opciones enumeradas enset
también son aceptadas por bash en su línea de comando; observe la primera oración en la sección Opciones del manual. página.
Respuesta
Todos los cambios de línea de comando de bash están documentados en man bash
.
-e Exit immediately if a pipeline (which may consist of a single simple command), a subshell command enclosed in parentheses, or one of the commands executed as part of a command list enclosed by braces (see SHELL GRAMMAR above) exits with a non-zero status. The shell does not exit if the command that fails is part of the command list immediately following a while or until keyword, part of the test following the if or elif reserved words, part of any command executed in a && or || list except the command following the final && or ||, any command in a pipeline but the last, or if the command"s return value is being inverted with !. A trap on ERR, if set, is executed before the shell exits. This option applies to the shell environment and each subshell envi- ronment separately (see COMMAND EXECUTION ENVIRONMENT above), and may cause subshells to exit before executing all the commands in the subshell.
Comentarios
- Ahh. Lo busqué en el hombre, pero después de encontrar -e en el archivo de pruebas y no -e bajo los argumentos principales me rendí. Buen extracto. Sin embargo, ¿por qué no se requiere
set
? : – /
Respuesta
Su secuencia de comandos es incorrecta, porque
egrep "^username" /etc/passwd >/dev/null if[ $? -eq 0 ] then #echo "doesn"t exist" # WRONG echo "the USER EXISTS" fi
estado de salida 0 – significa – todo está bien, en el caso de grep significa» OK, encontré la cadena «. estado de salida! = 0 significa que algo está mal, en el caso de grep 1 significa, «no encontrado», 2 significa «no puedo» abrir la entrada «…
-e
en la página de manual (realmente quiero ver una respuesta que aborde esto).$?
contiene el último código de salida (el del procesoegrep
generado anteriormente).-e
está documentado enset
.if egrep -q "^username" /etc/passwd ; then echo "doesn't exist" ; fi
if
y[
. Esta secuencia de comandos ganó ' t funcionar con-e
, porque sigrep
no ' t encuentra nada, entonces en-e
el script terminará allí mismo. Sin-e
, ' ha recibido el mensaje al revés: un estado ($?
) de 0 significa que grep encontró al usuario. Tenga en cuenta que, por cierto, debe ser `grep ' ^ username: ' (¿y si hay ' s otro usuario con un nombre más largo?).#/bin/bash -e
tendrá el mismo efecto que#/bin/bash
en la línea # 1 yset -e
en la línea # 2?