首页 > 解决方案 > Python 中 Bash 的 exec $@ 等价于什么?

问题描述

一些 bash 脚本以 结束它们的执行exec "$@",通常在最终用最初传递给脚本的参数替换它们的执行之前调用一系列命令。

如果你要编写一个 Python 脚本来替换那个 bash 脚本,最后的命令是什么?

标签: pythonbash

解决方案


在 bash 中,

"$@" 是所有位置参数 {$1, $2, $3 ...} 的类数组构造。

https://stackoverflow.com/a/5163260/1420079

因此exec "$@"将调用所有附加的位置参数,第一个参数是程序名称,然后是后续参数是该替换程序的参数。

在 Python 中,sys.argv(来自sys模块)是...

传递给 Python 脚本的命令行参数列表。argv[0] 是脚本名称(它是否为完整路径名取决于操作系统)。如果命令是使用解释器的 -c 命令行选项执行的,则 argv[0] 设置为字符串“-c”。如果没有将脚本名称传递给 Python 解释器,则 argv[0] 是空字符串。

https://docs.python.org/3/library/sys.html#sys.argv

用另一个替换当前正在运行的进程是os.exec*函数族的一项工作(不出所料,来自os模块),请参阅https://docs.python.org/3/library/os.html#os.execvp

exec如果调用Bash时不带-c标志,它会继承当前进程的环境,$PATH如果路径不是绝对路径,也会使用该变量查找要执行的程序。

因此,最接近的exec*函数是os.execvp可变数量的参数,使用路径)。另外要记住的是...

各种 exec* 函数获取加载到进程中的新程序的参数列表。在每种情况下,这些参数中的第一个作为它自己的名称而不是作为用户可能在命令行上键入的参数传递给新程序。对于 C 程序员,这是传递给程序 main() 的 argv[0]。例如, os.execvp('/bin/echo', ['foo', 'bar']) 只会在标准输出上打印 bar;foo 似乎会被忽略。


所以,我将exec "$@"在 Python 中实现 Bash,如下所示(假设os并被sys导入):

os.execvp(sys.argv[1], sys.argv[1:])

这不是一个完美的复制,Bash 的 exec 将不处理任何参数作为无操作,而这段代码将抛出一个IndexError.


推荐阅读