shell bash是否承诺在简单的情况下将-c优化为普通的exec?

khbbv19g  于 2023-05-29  发布在  Shell
关注(0)|答案(2)|浏览(97)

考虑下面的bash调用

bash -c 'sleep 99'

假设我运行它,在等待它结束睡眠时,我在另一个终端中运行ps。在这种情况下,我确实发现sleep 99正在运行。但是它的父进程不是运行bash -c的进程。相反,它的父进程是INVOKED bash -c。对此我只能想到一个解释:bash注意到,由于它被要求运行一个简单的命令,它执行了exec sleep 99的“优化”序列,而不是fork; exec sleep 99; wait; exit的“明显”序列。
我问这个问题的原因是,我今天注意到,在工作中,我们有一些Python脚本非常依赖于这种行为。(起初并不明显。我们使用subprocessshell=True…直到现在我才意识到这一点。)我试图将它们移植到Windows上,当然cmd.exe没有这样做,因为exec传统上不是Windows上的东西。
然后我想... bash做这件事的时候有没有文件记录?如果POSIX强制要求这样做,我会感到非常惊讶。我在bash用户手册中没有看到它。(虽然这是一本很大的手册。)你知道这能保证到什么程度吗?

w6mmgewl

w6mmgewl1#

(我个人很讨厌这个“聪明”的功能。
如果你想要的行为:

bash -c 'exec sleep 99'
  sh -c 'exec sleep 99'

如果你想避免这种行为:

bash -c 'sleep 99; exit'
  sh -c 'sleep 99; exit'
gdx19jrr

gdx19jrr2#

我们有一些Python脚本[...]使用subprocessshell=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重定向。

相关问题