我有一个 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中)