GNU/Linux >> Linux Esercitazione >  >> Linux

Bash Tcp Reindirizzamento Fine della trasmissione?

Ho creato un semplice servizio di rete con xinetd che legge una stringa dal socket tcp ed emette la sua vista codificata. Binario originale (qrencode) che legge solo stdin.

Funziona bene quando lo uso con netcat come echo string | nc <ip> <port>

Ma non risponde quando provo a usarlo tramite il reindirizzamento TCP bash.

exec 7<>/dev/tcp/<ip>/<port>
echo string >&7
cat <&7

Aspetta per sempre. Ho provato a fare eco a \004, cat /dev/null su questo fd e senza fortuna.
Come posso farlo funzionare?

Risposta accettata:

Quel inetd servizio o il tuo sta probabilmente aspettando EOF prima di uscire (e quindi chiudere la connessione).

Per fare ciò, è necessario che il client spenga il lato di invio del socket mantenendo aperto il lato di ricezione. Ecco cosa nc fa quando rileva EOF sul suo stdin.

Il /dev/tcp/host/port interfaccia virtuale di bash (copiato da ksh) non lo consente. Anche zsh 's ztcp un'alternativa più flessibile non ha la capacità di chiudere asimmetricamente le connessioni.

Potresti invece fare affidamento su un timeout, ma sarebbe inaffidabile. Quindi è meglio continuare a fare affidamento su utilità dedicate come nc o socat (possibilmente con un coproc per avere un'interfaccia simile) o utilizzare un linguaggio di programmazione con un'API di rete adeguata (con un'interfaccia per shutdown() ).

Il carattere 0x04 (^D ) significa EOF solo per i dispositivi terminali quando la disciplina di linea è in icanon mode (implementa un editor di linee grezze). Quindi, affinché funzioni, dovresti inserire uno pseudo-terminale tra il socket creato da xinetd e il tuo servizio Ad esempio, avviandolo con:

socat - exec:'your-service',pty,raw,icanon,echo=0,discard=,lnext=,werase=,kill=,start=,stop=,rprnt=,erase=,fdout=3

invece di

your-service

Quindi dovresti inviare:

printf 'text\n\4' >&7

Oppure:

printf 'text\4\4' >&7

per il tuo servizio per vedere la fine dell'input.

A causa di quell'editor di riga, your-service vedrà l'input solo quando invii newline o ^D caratteri (abbiamo disabilitato tutti gli altri caratteri di modifica come werase , erase , kill sopra e il ^C , ^Z … anche la gestione è disabilitata come parte di raw ).

Quindi potresti anche inserire un preprocessore di input invece che si chiude su quel carattere 0x4 come:

awk -v RS='\4' -v ORS= '{print; exit}' | your-service

(nota che awk non può essere mawk come mawk insiste nel non elaborare il suo input fintanto che non ha ricevuto un buffer pieno o eof).

Correlati:convertire la tabella in file ini usando gli array bash?
Linux
  1. È possibile che il completamento di Bash scorra le alternative?

  2. Come impostare i parametri quando Pipe Bash Script su Bash?

  3. Allegando vs. Non racchiudere il valore di una variabile tra virgolette in Bash?

  4. Risolto il problema con lo script Bash che prevedeva l'input del percorso con / alla fine si interrompe quando il percorso non termina con /?

  5. The Point Of The Bash Null-operatore “:”, Colon?

Usa questo utile script Bash quando osservi le stelle

Bash Shebang

Reindirizzamento Bash spiegato con esempi

Come aggiungere nuove righe nelle variabili in Bash Script?

Script Bash per eliminare tutti i file tranne N quando sono ordinati alfabeticamente

Quando disattivare TCP SACK?