终止运行中的命令当满足预期输出条件。

huangapple go评论119阅读模式
英文:

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 the grep command to match the name that is used above

  • grep 命令中去掉 logfile 中的美元符号,以匹配上面使用的名称

  • Use redirection without append to logfile so that continue 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 the grep command to match the name that is used above
  • Use redirection without append to logfile so that continue 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.

huangapple
  • 本文由 发表于 2023年3月7日 11:50:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/75657896.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定