英文:
Kill the running command when expected output is met
问题
以下是代码的翻译部分:
我有一个命令,它将执行一些操作并在屏幕上显示包含单词“continue”的消息。
一旦找到该单词,我想终止该命令。我尝试了下面的语法,但它不起作用。
Command_to_run >> "logfile" 2>&1 &
pid=$!
while ! grep -q "continue" "$logfile" ;
do
sleep 1
done
kill -$pid
英文:
I have a command which will do some activity will display message on screen that contains word "continue".
As soon as that word is found, I want to kill that command. I tried below syntax but it is not working.
Command_to_run >> "logfile" 2>&1 &
pid=$!
while ! grep -q "continue" "$logfile" ;
do
sleep 1
done
kill -$pid
答案1
得分: 2
以下是您要翻译的内容:
One method would be to have command_to_run
redirect the output to a pipe, and have the pipe closed as soon as the requested output appears in the output.
当请求的输出出现在输出中时,一种方法是让 command_to_run
将输出重定向到管道,并在请求的输出出现后立即关闭管道。
When the standard output is closed, most commands will exit as soon as they try to write something new to stdout.
当标准输出关闭时,大多数命令会在尝试向标准输出写入新内容时立即退出。
Here is an example of how this could be achieved:
以下是如何实现这一目标的示例:
File command_to_run
:
文件 command_to_run
:
#!/bin/bash
echo start
seq 2
echo continue
seq 10
echo end
$ ./command_to_run | tee logfile | awk '1;/continue/{exit}'
start
1
2
continue
Alternatively, if you don't need the output to appear in stdout, you can use grep
:
或者,如果您不希望输出出现在标准输出中,您可以使用 grep
:
./command_to_run | tee logfile | grep -q continue
$ cat logfile
start
1
2
continue
It's worth mentioning that the code in the OP almost works as well, it just needs some minor tweaks:
值得一提的是,OP 中的代码几乎可以正常工作,只需要进行一些小的调整:
-
remove the dollar sign from
logfile
in thegrep
command to match the name that is used above -
在
grep
命令中去掉logfile
中的美元符号,以匹配上面使用的名称 -
Use redirection without append to
logfile
so thatcontinue
string is not present from previous execution -
使用重定向而不是追加到
logfile
,以确保在上次执行中没有continue
字符串 -
add the end-of-options modifier
--
in the kill command so that the negative PID (group) is not evaluated as a signal number. -
在 kill 命令中添加选项结束符
--
,以防止将负 PID(进程组)解释为信号编号。
英文:
One method would be to have command_to_run
redirect the output to a pipe, and have the pipe closed as soon as the requested output appears in the output.
When the standard output is closed, most commands will exit as soon as they try to write something new to stdout.
Here is an example of how this could be achieved:
File command_to_run
:
#!/bin/bash
echo start
seq 2
echo continue
seq 10
echo end
$ ./command_to_run | tee logfile | awk '1;/continue/{exit}'
start
1
2
continue
Alternatively, if you don't need the output to appear in stdout, you can use grep
:
./command_to_run | tee logfile | grep -q continue
$ cat logfile
start
1
2
continue
It's worth mentioning that the code in the OP almost works as well, it just needs some minor tweaks:
- remove the dollar sign from
logfile
in thegrep
command to match the name that is used above - Use redirection without append to
logfile
so thatcontinue
string is not present from previous execution - add the end-of-options modifier
--
in the kill command so that the negative PID (group) is not evaluated as a signal number.
./command_to_run > "logfile" 2>&1 &
pid=$!
while ! grep -q "continue" "logfile" ;
do
sleep 1
done
kill -- -$pid
答案2
得分: 2
你可以使用 coproc
来实现这个功能。
#! /bin/bash
coproc ./command_to_run
until [[ $line =~ continue ]]; do
read -r -u ${COPROC[0]} line
done
kill $COPROC_PID
如果你真的需要日志文件,你可以在循环内部写入它。
英文:
You can use coproc
for that
#! /bin/bash
coproc ./command_to_run
until [[ $line =~ continue ]]; do
read -r -u ${COPROC[0]} line
done
kill $COPROC_PID
if you really want the log file you can write to it inside the loop.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论