我想得到bash的PID并在某些文本文件中突出显示它(假设它是)。所以当我在我的shell中输入它时:
grep -o $(pidof bash) test.txt
它只是工作正常并给我所需的输出,bash的PID。 那么为什么这个脚本不起作用:
#!/bin/bash
PID=$(grep -o $(pidof bash) test.txt)
echo $PID
我只得到一些:
grep:xxx:找不到文件或目录
xxx是随机数,但通常最后一个是我正在寻找的。 p>
我如何实现这一目标,为什么上述不起作用?
这与在shell中调用grep时shell创建新进程有关吗?
谢谢。
答案 0 :(得分:1)
当您在shell脚本中运行pidof
时,至少有两个bash实例正在运行,因此它将返回多个数字。设计grep的方式是,它一次只能搜索一个模式,因此第一个数字被解释为模式,其他数字被错误地解释为文件或目录名称。
我不确定您关心哪个bash PID,但一种解决方案是使用grep
,head
或tail
之类的内容来过滤{{}的输出1}}所以你只得到一个数字。另一个解决方案是使用特殊变量pidof
,它是评估它的bash实例的PID。
将来,您可以更好地自行调试。要进行调试,我首先要在脚本中运行此命令,以确切查看传递给$$
的参数:
grep
答案 1 :(得分:1)
我没有pidof
,所以我假设它等同于pgrep -v
,打印一个PID列表,每行一个,他们之间的换行符。
如果是这样,请考虑一下:
egrep -o "$(pgrep -v bash | tr '\n' '|')" test.txt
假设pgrep -v bash
的输出为:
123
456
789
您的原始代码会执行此操作:
egrep -o 123 456 789 test.txt
...因此,在名为123
的文件中,在名为456
的文件中以及名为789
的文件中搜索test.txt
。
现在,与使用管道符号替换该空格时的情况进行比较:
egrep -o "123|456|789" test.txt
...由本问题前面提到的管道执行正是您所寻找的。 (顺便说一句,这里的引用纯粹是语法 - 也就是说,当它理解如何解析事物而不是传递给egrep
时,它们会被shell使用。)
也就是说,如果您正在寻找当前 bash进程,请使用$$
(对于当前shell的父PID)或$BASH_PID
(对于当前shell本身,即使它是子shell ),而不是使用pgrep
或pidof
这样的不精确工具。