I want to open a port and listen for a command, and when that command comes in, immediately run a script.

The best I've come up with is (the echo is a substitute for my script):

nc -lk 9999 | grep -q runcommand && echo "running command"

, then I run this to test:

echo runcommand | nc localhost 9999

Unfortunately it only seems to echo the text on the second time I send "runcommand"??

How can I make grep exit immediately, so my script will run immediately?

  • that works for me with Debian's nc.openbsd (package netcat-openbsd) if I remove the -k option
    – ilkkachu
    Jul 31, 2021 at 8:45
  • @ilkkachu I wanted it to ignore the wrong command coming in, and stay listening. But I think without -k, the nc will exit if the wrong command comes in.
    – localhost
    Jul 31, 2021 at 9:26
  • ah, right. Though for what I got when testing was that with -k it just stays alive even when the grep exits... Now I'm wondering if there's differences between the variants and versions of netcat. I have two on my Debian, nc.openbsd and nc.traditional, I'm not sure if there's a third one too. But .traditional doesn't seem to have -k, so yours can't be that.
    – ilkkachu
    Jul 31, 2021 at 9:52
  • I threw some ideas in an answer, not sure if it works for you. Also, now that I check, I get your behavior on Mac.
    – ilkkachu
    Jul 31, 2021 at 13:24

1 Answer 1


One problem a construct like something | grep -q can have is that after grep exits, the left-hand command doesn't see the pipe close until it tries to write to it. But with my netcat (nc.openbsd from Debian), it doesn't seem to ever exit if -k is given, even if grep does. Hence the && never triggers. I did get the behavior you described with the netcat on macOS, though.

One possibility is to wrap netcat in a loop, this seems to work for me:

while true; do
    if nc -l 9999 | grep -q runcommand; then
        echo got correct string, exiting...
        echo got a connection, but not the correct string...

And of course if there's still a problem that just sending one line doesn't trigger netcat to exit, you could always send a dummy line after it to poke it:

printf "runcommand\n.\n" | nc localhost 9999

Not sure if this helps, and there might still be differences between the various netcats.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.