web-dev-qa-db-fra.com

Le script Bash ne restera pas ouvert en arrière-plan après avoir été exécuté pendant

Je ne peux pas faire en sorte que le script bash suivant reste ouvert après la réception du premier message de NC:

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

Après le premier message, il se ferme. Je veux qu'il reste ouvert et continue de surveiller les nouveaux messages de NC.

Je sais que si je lance nc -l port sans la boucle while, il reste ouvert et je peux discuter entre les deux connexions, même me déconnecter de l'hôte connecté.

J'envoie le message en utilisant:

echo 'done' | nc IP port
3
jfreak53

Ajoutez simplement une option -k à nc. Comme ça:

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

Comme on le voit dans man nc:

-k Force nc à rester à l'écoute d'une autre connexion une fois sa connexion actuelle établie. C'est une erreur d'utiliser cette option sans l'option -l.

3
Pavel A

Tu devrais utiliser -k option. nc -lk 3333

Tel qu'énoncé par 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.

Modifier:
Remarquez que mon camarade et moi-même avons affiché la même réponse presque simultanément. ( Comme l'esprit de celui-ci:) ) - Pour ne pas être complètement redondant, j'ajoute un échantillon à la fois en utilisant -k, et pas.

Premier:

Je sais que si je lance le port nc -l sans la boucle while, il reste ouvert et je peux discuter entre les deux connexions et même me déconnecter de l'hôte connecté.

Ce n'est pas le cas pour moi. Il se ferme après un message.

Seconde:

Je dirais -k, car il est fourni avec le logiciel et fonctionne correctement, serait la meilleure solution. Cependant, on pourrait également l'envelopper dans une boucle éternelle.

En utilisant -v pour obtenir plus d'informations.

#!/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

Et dans une autre 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

Aller un peu au-delà de la portée de la question; mais pourrait être pertinent dans certains cas: si vous utilisez un outil de vidage, c'est-à-dire Sudo tcpdump -i lo -vvv -w nc.cap vous remarquerez que vous obtenez:

Message "bonjour.\NComment allez-vous?\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
3
Runium