Esporre awk su tcp (inetd, socat, ecc.)


2

Stavo giocando con awk e volevo esporlo su un socket tcp.

All'inizio ci ho provato, ma ho fallito con micro-inetd. Pensando che forse il problema potrebbe essere nel modo in cui vengono gestiti i caratteri di ritorno a capo / newline, ho deciso di provare a passare a socat.

L'uso di un comando remoto con socat è abbastanza semplice:

socat TCP4-LISTEN:9000 EXEC:/bin/cat
socat TCP4-LISTEN:9000 SYSTEM:"/bin/python -i"

entrambi funzionano

Ma quando provo lo stesso con un semplice comando awk (ad esempio "awk" {print NR} "per contare progressivamente il numero di linee ricevute) non ottengo nulla indietro quando mi connetto con socat da un'altra shell sulla stessa macchina.

Ho provato molte cose (alcune di queste falliscono con un errore di sintassi che è un po 'oscuro per me. Non riesco nemmeno a cercare di stracciare socat per vedere esattamente cosa viene eseguito, dal momento che l'attuale comando che esegue è delegato alla shell) :

socat TCP4-LISTEN:9000 SYSTEM:"/usr/bin/awk '{print NR}'"
socat TCP4-LISTEN:9000 SYSTEM:'/usr/bin/awk "{print NR}"'
socat TCP4-LISTEN:9000 SYSTEM:'/usr/bin/awk "{print\ NR}"'

Ho anche creato una piccola sceneggiatura /tmp/testawk

#! /bin/sh
/usr/bin/awk '{print NR}'

(anche con una variante exec)

#! /bin/sh
exec /usr/bin/awk '{print NR}'

Entrambi funzionano localmente, ma quando si invoca

socat TCP4-LISTEN:9000 EXEC:/tmp/testawk

Non mi restituisce l'output

Pensando che il problema potrebbe essere l'ereditarietà degli handle stdin / stdout e / o ancora la gestione di crlf ... Ho provato anche con:

socat TCP4-LISTEN:9000 EXEC:/tmp/testawk,nofork
socat TCP4-LISTEN:9000,crnl EXEC:/tmp/testawk
socat TCP4-LISTEN:9000 EXEC:/tmp/testawk,crnl
socat TCP4-LISTEN:9000,crnl EXEC:/tmp/testawk,crnl

Ho trovato qualcun altro che si è lamentato di un problema simile , ma a quanto pare non è riuscito a ottenere alcuna attenzione

Qualche idea su cosa non va?

Risposte:


0

Puoi dire socatdi associare un pty al awkprogramma; questo obbliga awka funzionare in modalità buffer di linea e ottieni le risposte immediate che stai cercando.

Ecco la riga di comando per ascoltare sulla porta 9000:

socat TCP4-LISTEN:9000 SYSTEM:'/tmp/awk.sh',pty,echo=0

Ed ecco il contenuto dello script /tmp/awk.sh:

#!/usr/bin/awk -f
#
BEGIN   { print "This is the awk socket" }
        { print NR, $0 }
END     { print "All done" }

Esecuzione di esempio:

$ nc -vvv otherhost 9000
otherhost [192.168.1.15] 9000 (?) open
This is the awk socket
hello world
1       hello world
how are you
2       how are you
boo
3       boo
^C sent 28, rcvd 61

2

Awk sta stampando sullo standard output, che è bufferizzato in linea quando punta a un terminale, e completamente bufferato in caso contrario; questo significa che dovresti ottenere l'output dopo aver riempito il buffer, ovvero aver stampato (ad es.) 4KB.

Puoi testarlo inviando un sacco di output (ad es. Usando il programma yes); per risolvere il problema dovresti: - sbloccare lo stdout di awk (vedi ad esempio https://unix.stackexchange.com/a/25375/63847 ) - usa la chiamata di sistema shutdown (2) dal mittente (brutto)

Qualsiasi soluzione migliore è la benvenuta


Grazie, ci ho pensato, ma l'ho trascurato quando giocavo con diverse opzioni. Comunque ho provato con stdbuf -oL -eL /usr/bin/awk '{print NRq}'ma non riesco ancora a vedere nulla dall'altra parte
berdario

L' ptyopzione a quanto pare era quello che cercavo: stackoverflow.com/questions/6344501/...
berdario
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.