GNU/Linux >> Linux の 問題 >  >> Linux

終了コードの出所に関する詳細情報を取得するにはどうすればよいですか?

他のプログラムやスクリプトを呼び出すシェルスクリプトを呼び出すプログラムを維持する必要がある場合があります。したがって、メインシェルスクリプトが終了コード126で終了する場合、呼び出されたスクリプトとコマンドのどれがその終了コードを設定しているかを見つけるのは困難です。

どのコマンドが終了コードの理由であるかを確認して、そのアクセス許可を簡単に確認できるようにする方法はありますか?

承認された回答:

Linuxの場合は、strace -fe processでコマンドを実行できます。 どのプロセスがexit_group(126)を実行したかを知る そして、それを実行する前に最後に実行されたコマンド(またはそれ自体が何も実行しなかった場合はその親):

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

上記では、それが最初に126で終了したプロセス26326でした。これは、/を実行しようとしたためです。 。 sh -c /を最後に実行したのはプロセス26325の子でした 。

それらのスクリプトがbashの場合 スクリプトまたはshの場合 スクリプトとsh たまたまbash システムでは、次のことができます。

$ 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

126でどのプロセスが終了したかは正確にはわかりませんが、十分な手がかりが得られる可能性があります。

関連:findを使用して複数のファイルの名前を変更するにはどうすればよいですか?

BASH_TRACEFD=7 7>&2を使用します トレースがオリジナルに出力されるようにします stderrがスクリプト内でリダイレクトされた場合でも、stderr。そうしないと、これらのトレースメッセージが(....) 2>&1 | ... 。これは、これらのスクリプトがfd 7自体を明示的に使用したり閉じたりしないことを前提としています(これは、stderrをリダイレクトするよりもはるかに可能性が低いです)。


Linux
  1. Docker でコンテナに関する情報を取得する方法

  2. Linux でバイナリ実行可能ファイルを逆アセンブルしてアセンブリ コードを取得する方法は?

  3. bashでループの終了ステータスを取得する方法

  1. Kshのバージョンを安全に入手する方法は?

  2. 期待されるシェルスクリプトで生成されたプロセスの終了コードを取得するには?

  3. Linux マシンのハードウェアに関する詳細を調べるにはどうすればよいですか?

  1. 自動マウントのUSBキーを取得するにはどうすればよいですか?

  2. Pythonで(MB)ファイルのtar.gzのサイズを取得する方法

  3. Makefile でユーザー名を取得するにはどうすればよいですか?