スクリプトから親パスを取得する

スクリプトから親パスを取得する

foocallerRuby スクリプトを呼び出すbash スクリプトがありますfoo:

フーコーラー

/path/to/foo

内でfoo、 のパスを取得したいfoocallerこの提案そのために次のコードを追加しました:

フー

#!/usr/bin/env ruby
puts File.read("/proc/#{Process.ppid}/cmdline")

実行すると:

$ bash foocaller

すると、次の結果が得られます。

bash^@/path/to/foocaller

しかし、直接電話するとfoocaller

$ foocaller

すると次のようになります:

/bin/bash^@--noediting^@-i

へのパスが表示されません。を使わずにを直接呼び出してfoocallerへのパスを取得するにはどうすればよいでしょうか?foocallerfoocallerbash

答え1

多くのシェルは、スクリプト内の最後のコマンドを同じプロセスで実行することで最適化します。

$ sh -c 'ps
ps'
  PID TTY          TIME CMD
32673 pts/3    00:00:00 zsh
32696 pts/3    00:00:00 sh
32697 pts/3    00:00:00 ps
  PID TTY          TIME CMD
32673 pts/3    00:00:00 zsh
32696 pts/3    00:00:00 ps

ps最初に実行されたプロセス (32696) で2 番目が実行されsh、その親が の親sh(この場合はzsh対話型シェル) になっていることを確認します。

次の行を追加することでこれを回避できますexit

#! /bin/sh -
foo
exit

shは、終了foo後も解釈すべきことがまだあるため、同じプロセスで実行することはできません。そのため、代わりに別のプロセスで実行し、それを待機します。その後、を実行します(これにより、 と同じ終了ステータスでスクリプトが終了します)。foofooexitfoo

ここでプロセスを節約できたはずなので、これはあまり最適ではありません。

fooのパスについて知るためのより良い方法は、foocaller次のように伝えることです。

#! /bin/sh -
CALLER=$0 foo

次に、環境変数をfoo照会してCALLER、呼び出し元のパスを取得します(import os;print(os.environ["CALLER"])Pythonの場合)

関連情報