我有一個 bash 腳本foocaller
,它呼叫 ruby 腳本foo
:
foocaller
/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
。如何foocaller
透過直接呼叫foocaller
而不使用來獲取路徑bash
?
答案1
許多 shell 透過在同一進程中執行命令來最佳化腳本中的最後一個命令:
$ 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
是如何在最初運行的進程sh
(32696)中執行的,然後它的父進程是sh
的父進程(在我的例子中,zsh
是我的互動式 shell)。
您可以透過新增一行來避免這種情況exit
:
#! /bin/sh -
foo
exit
sh
無法在同一個進程中執行,因為完成foo
後仍有更多需要解釋。foo
因此它會foo
在另一個進程中運行並等待它。然後運行exit
(這將以與 相同的退出狀態退出腳本foo
)。
現在,這不是很理想,因為您可以在此處保存一個進程。
foo
了解 的路徑的更好方法foocaller
可能是告訴它:
#! /bin/sh -
CALLER=$0 foo
然後foo
可以查詢CALLER
環境變數來取得其呼叫者的路徑(import os;print(os.environ["CALLER"])
在python中)