Bash 在shell脚本中不执行复杂的grep命令

Bash 在shell脚本中不执行复杂的grep命令,bash,unix,grep,sh,Bash,Unix,Grep,Sh,我试图通过一个shell脚本来执行几个复杂的grep命令,该脚本在终端中手动执行。我一辈子都搞不懂为什么这样不行。 第一个grep的目标是获取附加到父myPattern的任何进程id。第二个获取进程模式的进程id 当前我的shell脚本 第一次不返回任何内容。 忽略第2部分中的“grep-v'grep'”部分 #!/bin/sh ps -ef | grep "$(ps -ef | grep 'myPattern' | grep -v grep | awk '{print $2}')" | gr

我试图通过一个shell脚本来执行几个复杂的grep命令,该脚本在终端中手动执行。我一辈子都搞不懂为什么这样不行。 第一个grep的目标是获取附加到父myPattern的任何进程id。第二个获取进程模式的进程id

当前我的shell脚本 第一次不返回任何内容。 忽略第2部分中的“grep-v'grep'”部分

#!/bin/sh

ps -ef | grep "$(ps -ef | grep 'myPattern' | grep -v grep | awk '{print $2}')" | grep -v grep | grep -v myPattern | awk '{print $2}'
ps -ef | grep 'myPattern' | grep -v 'grep' | awk '{print $2}'

当在终端中手动运行时,此功能可以正常工作。你知道我在哪里塞的吗?

你的第一个命令很模糊。我认为它不会像你描述的那样可靠。它也不能防止获得第一次grep调用的id。第二个适合我。对于FIST查询,这在很大程度上取决于您使用的系统。使用pstree可以更容易地显示pid下的整个流程树。比如:

pstree -p 1782 | sed 's/-/\n/g' | sed -n -e 's/.*(\([0-9]\+\)).*/\1/p'
您需要将pid限制为单个值。如果你有更多的值,那么你必须循环使用它们。如果您没有pstree,那么您可以围绕ps创建一些循环。请注意,即使当前命令有效,thwy也只能捕获一级父/子关系。pstree可以执行任何级别

我还必须告诉您,一个进程可以通过分叉将原始父进程转义为父进程

在任何情况下,如果没有确切的细节,你想实现什么,为什么,在什么平台上,很难给你一个好的答案。此外,这些实用程序虽然几乎无处不在,但并不像人们希望的那样便于携带

还有一个注释-/bin/sh通常不是您当前的shell。在许多linux系统上,用户的默认shell是bash,/bin/sh是dash或其他shell变体。所以,如果您看到控制台和脚本中的差异,则可能是您使用的实际shell中的差异

根据用户反馈,在java进程启动脚本中使用类似的内容会容易得多:

java <your params here> &
echo $! > /var/run/myprog.pid
java&
echo$!>/var/run/myprog.pid

然后kill脚本看起来像
echo/var/run/myprog.pid | xargs kill
。有较短的命令,但我认为这更便于携带。如果您想更具体,请给出实际代码。

对我来说很好。仅供参考,我使用`而不是$(如果您的意思是
bash
,那么最好在顶部使用
!/bin/bash
。您的系统可能有一个bourne外壳(或作为一个外壳反应)当你使用sh bang
#!/bin/sh
时,你会看到什么?祝你好运。避免使用
grep-v grep
的一个好方法是执行
grep[m]yPattern
这一切都是在solaris环境中完成的。我试图实现的目标是两步流程的一部分。第一个脚本用于启动一个shell脚本,该脚本执行java程序并在后台运行。第二个脚本需要能够终止该java流程。