GNU/Linux >> Linux Esercitazione >  >> Linux

Come ottenere ulteriori informazioni sull'origine di un codice di uscita?

A volte ho bisogno di mantenere programmi che invocano script di shell che invocano altri programmi e script. Pertanto, quando lo script della shell principale termina con il codice di uscita 126, è difficile scoprire quale degli script e dei comandi richiamati imposta quel codice di uscita.

C'è un modo per vedere quale comando è stato il motivo del codice di uscita per semplificare la verifica delle sue autorizzazioni?

Risposta accettata:

Se su Linux, puoi eseguire il comando in strace -fe process per sapere quale processo ha eseguito un exit_group(126) e quale comando esso (o uno qualsiasi dei suoi genitori se non ha eseguito nulla da solo) eseguito per ultimo prima di farlo:

$ 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 +++

Sopra, quello era il processo 26326 che è uscito per primo con 126, perché ha tentato di eseguire / . Era un figlio del processo 26325 che ha eseguito l'ultima volta sh -c / .

Se quegli script sono bash script o se sono sh script e sh sembra essere bash sul tuo sistema, potresti fare:

$ 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

Questo non ci dice esattamente quale processo è terminato con 126, ma potrebbe darti un indizio sufficiente.

Correlati:come rinominare più file usando trova?

Usiamo BASH_TRACEFD=7 7>&2 in modo che le tracce vengano emesse sull'originale stderr, anche quando stderr viene reindirizzato all'interno degli script. Altrimenti quei messaggi di traccia potrebbero influenzare il comportamento degli script se fanno cose come (....) 2>&1 | ... . Ciò presuppone che quegli script non utilizzino o chiudano esplicitamente fd 7 (sarebbe improbabile, molto più improbabile di reindirizzare stderr).


Linux
  1. Come ottenere in sicurezza la versione di Ksh?

  2. Come cercare i codici di uscita per le applicazioni?

  3. Come ottenere lo stato di uscita un ciclo in bash

  4. Come ottenere il codice di uscita del processo generato nello script di shell atteso?

  5. Come scoprire i dettagli sull'hardware sulla macchina Linux?

Come ottenere la dimensione di una directory in Linux

Come ottenere il massimo da Qmmp 1.0

Come ottenere informazioni su altri utenti Linux

Ottieni informazioni su un comando con Type Command in Linux

Come posso ottenere informazioni sul contenitore Docker Linux dall'interno del contenitore stesso?

Come trovare informazioni sulla RAM?