Manchmal muss ich Programme warten, die Shell-Skripte aufrufen, die wiederum andere Programme und Skripte aufrufen. Wenn das Haupt-Shell-Skript mit dem Exit-Code 126 endet, ist es daher schwierig herauszufinden, welches der aufgerufenen Skripte und Befehle diesen Exit-Code setzt.
Gibt es eine Möglichkeit zu sehen, welcher Befehl der Grund für den Exit-Code war, um die Überprüfung seiner Berechtigungen zu erleichtern?
Akzeptierte Antwort:
Unter Linux können Sie den Befehl unter strace -fe process
ausführen um zu wissen, welcher Prozess eine exit_group(126)
ausgeführt hat und welchen Befehl er (oder einer seiner Eltern, wenn er selbst nichts ausgeführt hat) zuletzt davor ausgeführt hat:
$ 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 +++
Oben war das der Prozess 26326, der zuerst mit 126 beendet wurde, weil er versuchte, /
auszuführen . Es war ein untergeordnetes Element von Prozess 26325, der zuletzt sh -c /
ausgeführt hat .
Wenn diese Skripte bash
sind Skripte oder wenn sie sh
sind Skripte und sh
ist zufällig bash
auf Ihrem System könnten Sie Folgendes tun:
$ 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
Das sagt uns nicht genau, welcher Prozess mit 126 beendet wurde, könnte Ihnen aber genügend Hinweise geben.
Verwandte:Wie benenne ich mehrere Dateien mit Find um?
Wir verwenden BASH_TRACEFD=7 7>&2
damit die Traces auf dem Original ausgegeben werden stderr, auch wenn stderr innerhalb der Skripte umgeleitet wird. Andernfalls könnten diese Trace-Meldungen das Verhalten der Skripte beeinflussen, wenn sie Dinge wie (....) 2>&1 | ...
. Das setzt voraus, dass diese Skripte nicht explizit fd 7 selbst verwenden oder schließen (das wäre unwahrscheinlich, viel unwahrscheinlicher, als dass sie stderr umleiten).