Take the 2-minute tour ×
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free, no registration required.

I can't get the following bash script to stay open after the first message is received from NC:

#!/bin/bash
port=3333
nc -l $port | while read msg; do notify-send Alert "$msg"; done

After the first message it exits. I want it to stay open and continue monitoring for new messages from NC.

I know that if I launch nc -l port without the while loop it stays open and I can chat away between the two connections even disconnect from the connected host.

I am sending the message using:

echo 'done' | nc IP port
share|improve this question

2 Answers 2

up vote 3 down vote accepted

Just add a -k option to nc. Like this:

nc -l $port -k | while read msg; do notify-send Alert "$msg"; done

As seen in man nc:

-k Forces nc to stay listening for another connection after its current connection is completed. It is an error to use this option without the -l option.

share|improve this answer

You should use -k option. nc -lk 3333

As stated by man nc

 -k      Forces nc to stay listening for another connection after its current
         connection is completed.  It is an error to use this option without the
         -l option.

Edit:
Notice me and my comrade here posted same answer close to simultaneously. (Like the mind of that one :)) – To not be completely redundant I'm adding a sample both using -k, and not.

First:

I know that if I launch nc -l port without the while loop it stays open and I can chat away between the two connections even disconnect from the connected host.

This is not the case for me. It closes after one message.

Second:

I'd say -k, as it is bundled with the software and works fine, would be the best way to go. However one could also wrap it within an eternal-loop.

Using -v to get some more information.

#!/bin/bash

nc1()
{
    nc -lkv $port | 
    while read msg; do 
        if [[ "$msg" =~ ^(q|quit|x|exit|halt)$ ]]; then
            printf ";; Received shut down signal \`%s'\n" "$msg"
            # Hack to terminate
            printf "\n" | nc localhost $port &
            break
        fi

        printf "MSG: %s\n" "$msg"
    done
}

nc2()
{
    while true; do
        msg=$(nc -lv $port)
        if [[ "$msg" =~ ^(q|quit|x|exit|halt)$ ]]; then
            printf ";; Received shut down signal \`%s'\n" "$msg"
            break
        fi

        printf "MSG: %s\n" "$msg"
    done
}

port=3333
fun=nc1

while [[ "$1" ]]; do
    case "$1" in
    1) fun=nc1;;
    2) fun=nc2;;
    p) port="$2"; shift;;
    *) printf "Unknown option \`%s'\n" "$1"
    esac
    shift
done

$fun

And in another session:

printf "hello.\nHow are you?\n" | nc localhost 3333; sleep 1; printf "Good bye.\n" | nc localhost 3333; sleep 1; printf "x\n" | nc localhost 3333

Going a bit beyond the scope of the question; but could be relevant in some cases: If you use some dump tool, i.e. sudo tcpdump -i lo -vvv -w nc.cap you'll notice that what you get is:

Message "hello.\nHow are you?\n":

1. TCP-connection; three-way handshake:

Client send     SYN
Server responds SYN, ACK
Client responds ACK

2. DATA

Client send     ACK, PUSH + message
Server responds ACK

3. TCP-termination; three-way handshake:

Client send     ACK, FIN
Server responds ACK, FIN
Client send     ACK
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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