考虑下面的bash调用
bash -c 'sleep 99'
假设我运行它,在等待它结束睡眠时,我在另一个终端中运行ps
。在这种情况下,我确实发现sleep 99
正在运行。但是它的父进程不是运行bash -c
的进程。相反,它的父进程是INVOKED bash -c
。对此我只能想到一个解释:bash注意到,由于它被要求运行一个简单的命令,它执行了exec sleep 99
的“优化”序列,而不是fork; exec sleep 99; wait; exit
的“明显”序列。
我问这个问题的原因是,我今天注意到,在工作中,我们有一些Python脚本非常依赖于这种行为。(起初并不明显。我们使用subprocess
和shell=True
…直到现在我才意识到这一点。)我试图将它们移植到Windows上,当然cmd.exe
没有这样做,因为exec
传统上不是Windows上的东西。
然后我想... bash做这件事的时候有没有文件记录?如果POSIX强制要求这样做,我会感到非常惊讶。我在bash用户手册中没有看到它。(虽然这是一本很大的手册。)你知道这能保证到什么程度吗?
2条答案
按热度按时间w6mmgewl1#
(我个人很讨厌这个“聪明”的功能。
如果你想要的行为:
如果你想避免这种行为:
gdx19jrr2#
我们有一些Python脚本[...]使用
subprocess
和shell=True
请注意,在UNIX-y系统(如Linux或Mac)上,这将不会启动Bash * 本身 *。相反,它将启动
/bin/sh
。这可能是也可能不是Bash(即使在Linux上),如果它是 * Bash,那么Bash在以该名称启动时以POSIX模式运行。bash做这件事的时候有没有文件记录?[...]我在Bash用户手册中没有看到它的提及。
我确信我对the manual的研究足以支持我的Assert,不,这种行为没有记录在案。手册页上也没有。我非常希望在源代码中提到,但那将是面向开发人员的,而不是面向用户的。
你知道这能保证到什么程度吗?
由于没有关于这种行为的用户文档,最好的答案可能是“根本没有”。当然,Bash是软件,所以如果你在一个案例中观察到这样的行为,你应该能够在足够相似的案例中依赖相同的行为,但是很难非常精确地描述“足够相似”。
在Python脚本中,如果实际上依赖Bash直接对指定的命令执行
exec
,则应强烈考虑不指定shell=True
。但请记住,确保没有插入 shell 并不是这样做的唯一效果。使用shell=True
的通常原因实际上是希望在命令中使用shell特性,例如I/O重定向。