linux 重复进程,关于linux:Bash:内联执行返回重复的“进程”。 为什么?

bash:4.3.42(1)-发行版(x86_64-pc-linux-gnu)

执行以下脚本:

# This is myscript.sh

line=$(ps aux | grep [m]yscript)  # A => returns two duplicates processes (why?)

echo"'$line'"

ps aux | grep [m]yscript          # B => returns only one

输出:

'tom   31836  0.0  0.0  17656  3132 pts/25   S+   10:33   0:00 bash myscript.sh

tom   31837  0.0  0.0  17660  1736 pts/25   S+   10:33   0:00 bash myscript.sh'

tom   31836  0.0  0.0  17660  3428 pts/25   S+   10:33   0:00 bash myscript.sh

为什么内联执行的ps -snippet(A)返回两行?

看来您正在运行两个脚本:`ps -ef | grep -E" 31837 | 31836"

命令替换($(...))

管道的每个部分[1]

导致Bash创建一个子Shell(通过分叉当前Shell进程创建的子进程),但是如果Bash导致一次调用外部实用程序,则Bash会优化掉子Shell。

(我认为在优化方案中发生的事情是实际上创建了一个子外壳,但是随后通过exec之类的东西立即被外部实用程序的进程所取代。如果您确定知道,请告诉我。)

应用于您的示例:

line=$(ps aux | grep [m]yscript)创建3个子进程:

1个子shell-您看到的脚本的分支,是grep返回的附加匹配项。

2个子进程(每个管道段1个)-ps和grep;它们代替了优化后的子外壳;它们的父进程是命令替换创建的剩余的1个子shell。

ps aux | grep [m]yscript创建2个子进程(每个管道段1个):

ps和grep;它们代替了优化后的子外壳;他们的父进程是当前的shell。

有关在Bash中创建子Shell的方案的概述,请参阅我的答案,但是,本文不涵盖优化方案。

[1]在Bash v4.2 +中,您可以设置选项lastpipe(默认情况下处于关闭状态),以使最后一个管道段在当前shell中而不是子shell中运行;除了稍微提高效率外,这还允许您在管道退出后当前shell可以看到的最后一段中声明变量。

我把支票交给另一个答案,因为它更快。 但是这个答案也很好。 谢谢

感谢您的反馈和支持,tokosh。 (我在@ John1024s之后写了这个答案,因为,尽管他的答案是有用和正确的,但我仍然觉得它缺少可在相关场景中提供帮助的背景信息-您绝对可以使用管道段创建的(非临时性)子shell结束 )

好的,我不得不承认"因为更快"是一个愚蠢的论点。 但是,我还是照原样保留了(你们两个都应该得到)。 因此,对于链接的答案,+ 1(不能做更多的事情)。

摘要

这将创建一个子外壳,因此两个进程正在运行:

line=$(ps aux | grep [m]yscript)

这不会创建子外壳。因此,myscript.sh仅运行一个进程:

ps aux | grep [m]yscript

示范

让我们稍微修改一下脚本,以便将流程和子流程的PID保存在变量line中:

$ cat myscript.sh

# This is myscript.sh

line=$(ps aux | grep [m]yscript; echo $$ $BASHPID)

echo"'$line'"

ps aux | grep [m]yscript

在bash脚本中,$$是脚本的PID,在子shell中未更改。相反,当输入子外壳程序时,bash使用子外壳程序的PID更新$BASHPID。

这是输出:

$ bash myscript.sh

'john1024  30226  0.0  0.0  13280  2884 pts/22   S+   18:50   0:00 bash myscript.sh

john1024   30227  0.0  0.0  13284  1824 pts/22   S+   18:50   0:00 bash myscript.sh

30226 30227'

john1024   30226  0.0  0.0  13284  3196 pts/22   S+   18:50   0:00 bash myscript.sh

在这种情况下,30226是主脚本上的PID,而30227是运行ps aux | grep [m]yscript的子外壳的PID。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值