GNU/Linux >> Tutoriales Linux >  >> Linux

¿Cómo obtener más información sobre el origen de un código de salida?

A veces necesito mantener programas que invocan scripts de shell que invocan otros programas y scripts. Por lo tanto, cuando el script de shell principal termina con el código de salida 126, es difícil averiguar cuál de los scripts y comandos invocados establece ese código de salida.

¿Hay alguna manera de ver qué comando fue el motivo del código de salida para que sea más fácil verificar sus permisos?

Respuesta aceptada:

Si está en Linux, puede ejecutar el comando en strace -fe process para saber qué proceso hizo un exit_group(126) y qué comando ejecutó (o cualquiera de sus padres si no ejecutó nada por sí mismo) antes de hacer eso:

$ strace -fe process sh -c 'env sh -c /; exit'
execve("/bin/sh", ["sh", "-c", "env sh -c /; exit"], [/* 53 vars */]) = 0
arch_prctl(ARCH_SET_FS, 0x7f24713b1700) = 0
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f24713b19d0) = 26325
strace: Process 26325 attached
[pid 26324] wait4(-1,  <unfinished ...>
[pid 26325] execve("/usr/bin/env", ["env", "sh", "-c", "/"], [/* 53 vars */]) = 0
[pid 26325] arch_prctl(ARCH_SET_FS, 0x7fbdb4e2c700) = 0
[pid 26325] execve("/bin/sh", ["sh", "-c", "/"], [/* 53 vars */]) = 0
[pid 26325] arch_prctl(ARCH_SET_FS, 0x7fef90b3b700) = 0
[pid 26325] clone(strace: Process 26326 attached
child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7fef90b3b9d0) = 26326
[pid 26325] wait4(-1,  <unfinished ...>
[pid 26326] execve("/", ["/"], [/* 53 vars */]) = -1 EACCES (Permission denied)
sh: 1: /: Permission denied
[pid 26326] exit_group(126)             = ?
[pid 26326] +++ exited with 126 +++
[pid 26325] <... wait4 resumed> [{WIFEXITED(s) && WEXITSTATUS(s) == 126}], 0, NULL) = 26326
[pid 26325] --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=26326, si_uid=10031, si_status=126, si_utime=0, si_stime=0} ---
[pid 26325] exit_group(126)             = ?
[pid 26325] +++ exited with 126 +++
<... wait4 resumed> [{WIFEXITED(s) && WEXITSTATUS(s) == 126}], 0, NULL) = 26325
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=26325, si_uid=10031, si_status=126, si_utime=0, si_stime=0} ---
exit_group(126)                         = ?
+++ exited with 126 +++

Arriba, ese fue el proceso 26326 que salió primero con 126, eso fue porque intentó ejecutar / . Fue un hijo del proceso 26325 que ejecutó por última vez sh -c / .

Si esos scripts son bash guiones o si son sh guiones y sh pasa a ser bash en su sistema, podría hacer:

$ env SHELLOPTS=xtrace 
      BASH_XTRACEFD=7 7>&2 
      PS4='[$?][$BASHPID|${BASH_SOURCE:-$BASH_EXECUTION_STRING}|$LINENO]+ '  
    sh -c 'env sh -c /; exit'
[0][30625|env sh -c /; exit|0]+ env sh -c /
[0][30626|/|0]+ /
sh: /: Is a directory
[126][30625|env sh -c /; exit|0]+ exit

Eso no nos dice exactamente qué proceso salió con 126, pero podría darle suficiente pista.

Relacionado:¿Cómo cambiar el nombre de varios archivos usando buscar?

Usamos BASH_TRACEFD=7 7>&2 para que las huellas se emitan en el original stderr, incluso cuando stderr se redirige dentro de los scripts. De lo contrario, esos mensajes de rastreo podrían afectar el comportamiento de los scripts si hacen cosas como (....) 2>&1 | ... . Eso supone que esos scripts no usan ni cierran explícitamente fd 7 (eso sería poco probable, mucho más improbable que redirigir stderr).


Linux
  1. Cómo obtener información sobre un contenedor en Docker

  2. ¿Cómo desensamblar un ejecutable binario en Linux para obtener el código de ensamblaje?

  3. Cómo obtener el estado de salida de un bucle en bash

  4. ¿Cómo obtener el PYTHONPATH en shell?

  5. ¿Cómo obtener la identificación del proceso para eliminar un proceso nohup?

Cómo obtener el tamaño de un directorio en Linux

Cómo aprovechar al máximo Qmmp 1.0

Cómo obtener información sobre otros usuarios de Linux

Obtener información sobre un comando con tipo de comando en Linux

¿Cómo obtener el código de salida del proceso generado en el script de shell esperado?

¿Cómo encontrar información sobre la memoria RAM?