2013-05-23 13 views
59

Funziona bene come un unico strumento:Perché CURL restituisce ed errore (23) Scrittura non riuscita del corpo?

curl "someURL" 
curl -o - "someURL" 

ma non funziona in una pipeline:

curl "someURL" | tr -d '\n' 
curl -o - "someURL" | tr -d '\n' 

restituisce:

(23) Failed writing body 

Qual è il problema nel piping l'uscita arricciatura? Come bufferizzare l'intero output dell'arricciatura e poi gestirlo?

+1

Per me funziona, non c'è bisogno di buffer. – hek2mgl

+0

funziona anche in pipeline ?: 'curl 'http://www.multitran.ru/c/m.exe?CL=1&s=hello&l1=1' | tr -d '\ n'' – static

+0

Sì, certo .. Provato con il tuo url – hek2mgl

risposta

9

Quindi è stato un problema di codifica. Iconv risolve il problema

curl 'http://www.multitran.ru/c/m.exe?CL=1&s=hello&l1=1' | iconv -f windows-1251 | tr -dc '[:print:]' | ... 
3

È possibile fare questo, invece di utilizzare -o opzione:

curl [url] > [file]

+0

quindi, non usare la pipe e invece fare tutto il lavoro sul file system? Volevo usare l'uscita del ricciolo con i tubi. – static

+2

La domanda dice che solo le sequenze in pipe non funzionano. – Det

45

Ciò accade quando un programma convogliato (es grep) chiude il condotto di lettura prima che il programma precedente è terminata scrivendo l'intera pagina.

In , non appena grep ha ciò che desidera, chiuderà il flusso di lettura dall'arricciatura. cURL non si aspetta questo ed emette l'errore "Failed writing body".

Una soluzione alternativa consiste nel convogliare il flusso attraverso un programma intermedio che legge sempre l'intera pagina prima di inviarlo al programma successivo.

E.g.

curl "url" | tac | tac | grep -qs foo 

tac è un semplice programma Unix che legge l'intera pagina di ingresso ed inverte l'ordine linea (da qui si corre due volte). Poiché deve leggere l'intero input per trovare l'ultima riga, non restituirà nulla a grep fino a quando cURL non sarà terminato. Grep chiuderà comunque il flusso letto quando ha quello che sta cercando, ma influenzerà solo tac, che non emetterà un errore.

+1

Non potresti semplicemente collegarlo a 'cat' una volta? Risolve il problema per me, almeno. – benvd

+3

No. Potrebbe essere utile con documenti di piccole dimensioni, ma quando è troppo grande per adattarsi al buffer cat, verrà visualizzato l'errore. È possibile utilizzare '-s' per disattivare tutti i messaggi di errore (e lo stato di avanzamento) se non sono necessari . – Kaworu

+2

'tac | tac' cambia l'input se l'input non termina con un linefeed, o per esempio' printf a \\ nb \\ nc | tac | tac' stampa 'a \ ncb' dove' \ n' è un avanzamento di riga. Puoi usare 'sponge/dev/stdout' invece. Un'altra opzione è 'printf% s \\ n" $ (cat) "', ma quando l'input contiene byte null in shell diverse da Zsh, questo salta i byte null o interrompe la lettura dopo il primo byte null. – user4669748

7

(Per completezza e ricerche future) E 'il modo in cui CURL gestisce il buffer, il buffer disabilita il flusso di output con l'opzione -N.

ES: curl -s -N "URL" | grep -q Welcome

+1

che non funziona. –

+4

Questo * funziona *! Grazie! –

+1

Ha funzionato per 'curl -s https://raw.githubusercontent.com/hermitdave/FrequencyWords/master/content/2016/ro/ro_50k.txt | testa -20' (senza '-s' ottengo lo stesso errore). –

4

ho avuto lo stesso errore, ma dalla ragione diversa. Nel mio caso ho avuto (tmpfs) partizione con solo 1 GB di spazio e stavo scaricando file di grandi dimensioni che finalmente riempiva tutta la memoria su quella partizione e ho ottenuto lo stesso errore che hai.

1

Un'altra possibilità, se si utilizza l'opzione -o (file di output), la directory di destinazione non esiste.

es. se hai -o /tmp/download/abc.txt e/tmp/download non esiste.

Quindi, garantire tutte le directory necessarie vengono create/esistono in precedenza, utilizzare l'opzione --create-dirs nonché - se necessario o

1

ho incontrato questo messaggio di errore durante il tentativo di installare la cache di vernice su Ubuntu. La ricerca di Google mi ha inviato qui per l'errore (23) Failed writing body, quindi pubblicando una soluzione che ha funzionato per me.

Il bug si verifica durante l'esecuzione del comando come root curl -L https://packagecloud.io/varnishcache/varnish5/gpgkey | apt-key add -

la soluzione è quello di eseguire apt-key add come non radice

curl -L https://packagecloud.io/varnishcache/varnish5/gpgkey | apt-key add - 
0

Il server ha esaurito lo spazio su disco, nel mio caso.

Controllare con df -k .

fui avvisato della mancanza di spazio sul disco quando provai tubazioni attraverso tac due volte, come descritto in una delle altre risposte: https://stackoverflow.com/a/28879552/336694. Mi ha mostrato il messaggio di errore write error: No space left on device.