简体   繁体   中英

Can't terminate command from a different process

I have a command "command1" that runs indefinitely (must be killed with Ctrl+c), and that at random intervals outputs new lines to stdout. My goal is to run it and see if it outputs a certain "target" line within 10 seconds. If the target output is generated, stop immediately with success, otherwise wait for the 10 seconds and fail.

I came up with this:

timeout 10 bash -c '(while read line; do [[ "$line" == "target" ]] && break; done < <(command1))'

It works, but the problem is that when a match is found, although the timeout command completes and returns successfully, command1 will continue to run indefinitely as a background process. I need it to stop as well when "break" is executed. If a match is not found, and the timeout expires, command1 is stopped correctly.

I also tried this:

timeout 10 bash -c '(command1 | while read line; do [[ "$line" == "target" ]] && exit; done)'

Which does not leave any spurious processes running. The problem is that the exit command does not terminate command1 since it is in a separate process, and the timeout always expires even if the target is found before.

I was exploring some alternative options, such as wait -n, but the same problem persists, and I must use bash 4.2, so wait -n isn't even an option.

Any suggestions would be greatly appreciated.

When command1 does not terminate itself, you can kill it manually.
By the way: Instead of while read ... you can use grep .

timeout 10 bash -c 'command1 | (grep -m1 -Fx "target"; pkill -P $PPID command1)'

-P $PPID ensures that only the command1 from this command is killed, and not some other command1 that might run in another shell at the same time.

This assumes that command1 is a single command, and not something like (cmd1; cmd2; ...) . For that case, you could simply kill the whole bash process using kill $PPID .

Found what works best for my case:

timeout 10 bash -c 'grep -q -m1 "target" <(command1); pkill -P $!'

All processes terminate gracefully when either the target is found or the timeout expires. If found, command returns 0, if not found, command returns 124. Thank you @Socowi for some very helpful hints that put me on the right track.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM