此处文档中的bash脚本未按预期运行
下面是一个失败的最小测试用例此处文档中的bash脚本未按预期运行,bash,Bash,下面是一个失败的最小测试用例 #!/bin/tcsh #here is some code in tcsh I did not write which spawns many processes. #let us pretend that it spawns 100 instances of stupid_test which the user kills #manually after an indeterminate period /bin/bash <<EOF #!/bin
#!/bin/tcsh
#here is some code in tcsh I did not write which spawns many processes.
#let us pretend that it spawns 100 instances of stupid_test which the user kills
#manually after an indeterminate period
/bin/bash <<EOF
#!/bin/bash
while true
do
if [[ `ps -e | grep stupid_test | wc -l` -gt 0 ]]
then
echo 'test program is still running'
echo `ps -e | grep stupid_test | wc -l`
sleep 10
else
break
fi
done
EOF
echo 'test program finished'
预期的行为是运行,直到愚蠢的_测试被终止(在这种情况下,由用户手动),然后在接下来的十秒钟内终止。观察到的行为是,即使在程序被终止后,脚本也不会终止,并计算ps-e | grep dumby|u test | wc-l
==1(并且它不再显示在ps下)
如果bash脚本直接运行,而不是在here文档中运行,则会恢复预期的行为
我觉得我做错了什么愚蠢的事,我根本不是最有经验的黑客。它为什么这样做?通常,当您尝试
grep
进程名称时,会为grep
本身获得额外的匹配行,例如:
$ ps xa | grep something
57386 s002 S+ 0:00.01 grep something
因此,即使没有匹配过程,也会得到一条匹配行。您可以通过在管道中添加grep-v grep
来解决此问题:
ps -e | grep stupid_test | grep -v grep | wc -l
正如所建议的,一个更好的修复方法是像这样编写grep
:
ps -e | grep [s]tupid_test
模式的含义完全相同,但这样它将不再匹配grep
本身,因为字符串“grep[s]tupid\u test”
与正则表达式/[s]tupid\u test/
不匹配
顺便说一句,我会像这样重写你的脚本,cleaner:
/bin/bash <<EOF
while :; do
s=$(ps -e | grep [s]tupid_test)
test "$s" || break
echo test program is still running
echo "$s"
sleep 10
done
EOF
/bin/bash如果你想调用bash
,那么你需要/bin/bash,你也有一些野性。pgrep对于这种情况是非常有用的工具。如果我使用ps-x
,我观察到ps的行为,但是对于ps-e
@aestrivex,你在哪种操作系统中?在Linux中可以ps-e
也像你对我说的那样工作。在中间,如果不是行计数,就让它用<代码> PS-E.GRP-StudioTyTest打印匹配过程,然后您应该得到一些行,匹配过程将循环从退出作为进一步的优化,<代码> GRP'[StupIDyTest >避免首先匹配自身。
/bin/bash <<EOF
while :; do
s=$(ps -e | grep [s]tupid_test)
test "$s" || break
echo test program is still running
echo "$s"
sleep 10
done
EOF
/bin/bash <<EOF
while ps -e | grep [s]tupid_test
do
echo test program is still running
sleep 10
done
EOF