* nix世界でシェルスクリプトがどのプログラムを実行したかについての情報を取得する方法はありますか?
例:
/path/to/script1 /path/to/script_xyz
この仮想シナリオでは、パス情報()script_xyz
があります。/path/to/script1
または
プロセスPID
これを実行するエンティティです。
注:さまざまなソリューションとアプローチが気になります。実際にはできないようです。
ベストアンサー1
プロセスブランチと実行の間に混乱が頻繁に発生します。
シェルプロンプトでこれを行うときbash
。
$ sh -c 'exec env ps'
プロセスP1$
コードが現在実行されている間にこのプロンプトを発行してくださいbash
。このbash
コードは新しいプロセスをフォークしますP2そして/bin/sh
また/usr/bin/env
やってください/bin/ps
。
だからP2bash
、、、sh
のコードenv
が順番に実行されますps
。
ps
env
(またはここで使用するスクリプトなどの他のコマンド)は、コマンドが実行されたかどうかを知りません。
できることは、親プロセスIDが何であるかを調べることだけです。この場合、P1または1
、P1この間隔内に死亡したか、Linuxでは、次のように指定された別のものが死亡しました。代理死神変える1
。
その後、プロセスがどのコマンドであるかをシステムに照会できます。今実行中またはreadlink /proc/<pid>/exe
実行された最後のコマンド(Linuxと同様)に渡された引数(Linuxと同様ps -o args= -p <pid>
)。
スクリプトが何を呼び出したかを知りたい場合は、呼び出し元にこれを知らせることが信頼できる方法です。たとえば、環境変数を使用してこれを実行できます。たとえば、次のようscript1
に書くことができます。
#! /bin/sh -
INVOKER=$0 script2 &
そしてscript2
:
#! /bin/sh -
printf '%s\n' "I was invoked by $INVOKER"
# and in this case, we'll probably find the parent process is 1
# (if not now, at least one second later) as script1 exited just after
# invoking script2:
ps -fp "$$"
sleep 1
ps -fp "$$"
exit
$INVOKER
します(一般的に言えば)にはへのパスが含まれていますscript1
。場合によっては、相対パスである可能性があり、パスは開始時に現在の作業ディレクトリに相対的ですscript1
。したがって、script1
呼び出す前に現在の作業ディレクトリを変更すると、そのディレクトリがscript2
呼び出さscript2
れた場所に関する誤った情報が得られます。したがって、$INVOKER
次のように絶対パス(デフォルト名を維持することをお勧めします)を含めるのが最善ですscript1
。
#! /bin/sh -
mypath=$(
mydir=$(dirname -- "$0") &&
cd -P -- "$mydir" &&
pwd -P) && mypath=$mypath/$(basename -- "$0") || mypath=$0
... some code possibly changing the current working directory
INVOKER=$mypath script2
POSIXシェルには、$PPID
シェルの初期化時にシェルを実行した親プロセスのpidが含まれています。後で上記のようにIDを持つプロセスが$PPID
終了すると、親プロセスが変更される可能性があります。
zsh
zsh/system
モジュールから問い合わせることができます。現在の現在(サブ)シェルの上位pidで、サフィックスが付きます$sysparams[ppid]
。 POSIXシェルでは、次のことができます。現在のインタプリタを実行するプロセスのppid(まだ実行中であると仮定)ps -o ppid= -p "$$"
。を使用して、bash
現在の(サブ)シェルのppidを取得できますps -o ppid= -p "$BASHPID"
。