¿Cuál es el $? (signo de interrogación del dólar) variable en shell scripting?

Estoy tratando de aprender scripting de shell, y necesito entender el código de otra persona. ¿Cuál es el $? retención variable? No puedo buscar en Google la respuesta porque bloquean los caracteres de puntuación.

$? se usa para encontrar el valor de retorno del último comando ejecutado. Pruebe lo siguiente en el shell:

 ls somefile echo $? 

Si existe algún archivo (independientemente de si se trata de un archivo o directorio), obtendrá el valor devuelto por el comando ls , que debería ser 0 (valor de retorno “satisfactorio” predeterminado). Si no existe, debe obtener un número distinto de 0. El número exacto depende del progtwig.

Para muchos progtwigs, puede encontrar los números y su significado en la página man correspondiente. Estos generalmente se describirán como “estado de salida” y pueden tener su propia sección.

Ese es el estado de salida de la última función / progtwig / comando ejecutado. Referirse a:

  • estado de salida / salida @ tldp.org
  • Special Shell Variables @ tldp.org
  • Caracteres Especiales @ tlpd.org

Un valor de retorno del proceso ejecutado previamente.

10.4 Obtener el valor de retorno de un progtwig

En bash, el valor de retorno de un progtwig se almacena en una variable especial llamada $ ?.

Esto ilustra cómo capturar el valor de retorno de un progtwig, supongo que el directorio dada no existe. (Esto también fue sugerido por Mike)

  #!/bin/bash cd /dada &> /dev/null echo rv: $? cd $(pwd) &> /dev/null echo rv: $? 

Vea el Manual de progtwigción de Bash para más detalles.

ps es el resultado (código de salida) del último comando ejecutado.

Ejemplo de Minimal C

Para entender $? , primero debe comprender el concepto de estado de salida del proceso.

En Linux:

  • Cuando un proceso llama a la llamada al sistema de exit , el núcleo almacena el valor pasado a la llamada del sistema incluso después de que el proceso muere.

    La llamada al sistema de salida es llamada por la función exit() ANSI C e indirectamente cuando return desde main .

  • el proceso que llamó al proceso hijo que sale (Bash), a menudo con fork + exec , puede recuperar el estado de salida del niño con la llamada al sistema de wait

Considera el código de Bash:

 $ false $ echo $? 1 

El “equivalente” C es:

false.c:

 #include  /* exit */ int main() { exit(1); } 

bash.c:

 #include  /* execl */ #include  /* fork */ #include  /* wait, WEXITSTATUS */ #include  /* printf */ int main() { if (fork() == 0) { /* Call false. */ execl("./false", "./false", (char *)NULL); } int status; /* Wait for a child to finish. */ wait(&status); /* Status encodes multiple fields, * we need WEXITSTATUS to get the exit status: * http://stackoverflow.com/questions/3659616/returning-exit-code-from-child **/ printf("$? = %d\n", WEXITSTATUS(status)); } 

En Bash, cuando presionas enter, un fork + exec + wait sucede como arriba, y bash entonces establece $? al estado de salida del proceso bifurcado.

Nota: para comandos incorporados como echo , no es necesario echo un proceso, y Bash simplemente establece $? a 0 para simular un proceso externo.

Estándares y documentación

POSIX 7 2.5.2 “Parámetros especiales” http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_05_02 :

? Se expande al estado de salida decimal de la tubería más reciente (consulte Tuberías).

man bash “Parámetros especiales”:

La carcasa trata varios parámetros especialmente. Estos parámetros solo pueden ser referenciados; la asignación a ellos no está permitida. […]

? Se expande al estado de salida de la tubería de primer plano ejecutada más recientemente.

ANSI C y POSIX luego recomiendan que:

  • 0 significa que el progtwig fue exitoso

  • otros valores: el progtwig falló de alguna manera.

    El valor exacto podría indicar el tipo de falla.

    ANSI C no define el significado de ningún valor, y POSIX especifica valores mayores que 125: Nunca entendí realmente: ¿qué es POSIX?

Bash usa el estado de salida if

En Bash, a menudo usamos el estado de salida $? implícitamente para controlar if declaraciones como en:

 if true; then : fi 

donde true es un progtwig que simplemente devuelve 0.

Lo anterior es equivalente a:

 true result=$? if [ $result = 0 ]; then : fi 

Y en:

 if [ 1 = 1 ]; then : fi 

[ es solo un progtwig con un nombre raro (y Bash incorporado que se comporta como este), y 1 = 1 ] sus argumentos, vea también: ¿Cuál es la diferencia entre los corchetes simples y dobles en Bash?

Es el código de error devuelto del último comando ejecutado. 0 = éxito

$? es el estado de salida de un comando, de modo que puede conectar en serie una serie de comandos.

Ejemplo

 command1 && command2 && command3 

command2 se ejecutará si command1's $? produce un success (0) y command3 se ejecutará si $? de command2 rendirá un success

El código de salida del último comando se ejecutó.

Es adecuado para la depuración en caso de que su script salga si se usa “set -e”. Por ejemplo, pon “echo $?” después del comando que hace que salga y vea el valor de error devuelto.