Es funktioniert gut als einzelnes Werkzeug:
curl "someURL"
curl -o - "someURL"
aber es funktioniert nicht in einer Pipeline:
curl "someURL" | tr -d '\n'
curl -o - "someURL" | tr -d '\n'
es gibt zurück:
(23) Failed writing body
Was ist das Problem beim Weiterleiten des cURL-Ausgangs? Wie kann man die gesamte cURL-Ausgabe puffern und dann damit umgehen?
curl 'http://www.multitran.ru/c/m.exe?CL=1&s=hello&l1=1' | tr -d '\n'
iconv -f ...
Antworten:
Dies geschieht, wenn ein Pipeline-Programm (z. B. grep) die Lese-Pipe schließt, bevor das vorherige Programm das Schreiben der gesamten Seite beendet hat.
In
curl "url" | grep -qs foo
, sobald grep hat , was es will , es wird der Lesestrom von curl schließen. cURL erwartet dies nicht und gibt den Fehler "Fehlerhafter Schreibkörper" aus.Eine Problemumgehung besteht darin, den Stream durch ein Zwischenprogramm zu leiten, das immer die gesamte Seite liest, bevor es dem nächsten Programm zugeführt wird.
Z.B
tac
ist ein einfaches Unix-Programm, das die gesamte Eingabeseite liest und die Zeilenreihenfolge umkehrt (daher führen wir sie zweimal aus). Da die gesamte Eingabe gelesen werden muss, um die letzte Zeile zu finden, wird nichts ausgegeben, um grep auszuführen, bis cURL beendet ist. Grep schließt den Lesestream immer noch, wenn es das hat, wonach es sucht, aber es wirkt sich nur auf tac aus, das keinen Fehler ausgibt.quelle
cat
einmal durchpfeifen? Löst das Problem zumindest für mich.-s
angezeigt. Sie können alle Fehlermeldungen (und den Fortschritt) stumm schalten, wenn Sie sie nicht benötigen.tac|tac
Ändert die Eingabe, wenn die Eingabe nicht mit einem Zeilenvorschub endet oder beispielsweiseprintf a\\nb\\nc|tac|tac
gedruckt wird,a\ncb
wo\n
sich ein Zeilenvorschub befindet. Sie könnensponge /dev/stdout
stattdessen verwenden. Eine andere Option istprintf %s\\n "$(cat)"
, aber wenn die Eingabe Null-Bytes in anderen Shells als Zsh enthält, werden entweder die Null-Bytes übersprungen oder das Lesen nach dem ersten Null-Byte beendet.tac
unter macOS keinen Befehl gibtFür die Vollständigkeit und zukünftige Suche:
Es kommt darauf an, wie cURL den Puffer verwaltet. Der Puffer deaktiviert den Ausgabestream mit der Option -N.
Beispiel:
curl -s -N "URL" | grep -q Welcome
quelle
curl -s https://raw.githubusercontent.com/hermitdave/FrequencyWords/master/content/2016/ro/ro_50k.txt | head -20
(ohne dass-s
ich den gleichen Fehler bekomme).Eine andere Möglichkeit, wenn Sie die
-o
Option (Ausgabedatei) verwenden - das Zielverzeichnis existiert nicht.z.B. wenn du hast
-o /tmp/download/abc.txt
und / tmp / download nicht existiert.Stellen Sie daher sicher, dass alle erforderlichen Verzeichnisse im Voraus erstellt wurden / vorhanden sind, und verwenden Sie die
--create-dirs
Option sowie -o
falls erforderlichquelle
Es war also ein Problem bei der Codierung. Iconv löst das Problem
quelle
Sie können dies tun, anstatt die
-o
Option zu verwenden:curl [url] > [file]
quelle
Ich hatte den gleichen Fehler, aber aus verschiedenen Gründen. In meinem Fall hatte ich eine (tmpfs) Partition mit nur 1 GB Speicherplatz und lud eine große Datei herunter, die schließlich den gesamten Speicher auf dieser Partition füllte , und ich bekam den gleichen Fehler wie Sie.
quelle
In meinem Fall ging dem Server der Speicherplatz aus.
Überprüfen Sie es mit
df -k .
Ich wurde auf den Mangel an Speicherplatz aufmerksam gemacht, als ich
tac
zweimal versuchte, durchzuleiten , wie in einer der anderen Antworten beschrieben: https://stackoverflow.com/a/28879552/336694 . Es zeigte mir die Fehlermeldungwrite error: No space left on device
.quelle
docker system prune
Der Fehler tritt auf, wenn der Befehl als root ausgeführt wird
curl -L https://packagecloud.io/varnishcache/varnish5/gpgkey | apt-key add -
Die Lösung besteht darin,
apt-key add
als Nicht-Root ausgeführt zu werdenquelle
Wenn Sie etwas Ähnliches versuchen
source <( curl -sS $url )
und den(23) Failed writing body
Fehler erhalten, liegt dies daran, dass die Beschaffung einer Prozessersetzung nicht funktioniertbash 3.2
(Standardeinstellung für macOS).Stattdessen können Sie diese Problemumgehung verwenden.
quelle
Für mich war es eine Erlaubnisfrage. Der Docker-Lauf wird mit einem Benutzerprofil aufgerufen, aber root ist der Benutzer im Container. Die Lösung bestand darin, Curl in / tmp schreiben zu lassen, da dies Schreibberechtigung für alle Benutzer hat, nicht nur für root.
Ich habe die Option -o verwendet.
-o / tmp / file_to_download
quelle
In Bash und zsh (und möglicherweise in anderen Shells) können Sie die Prozessersetzung ( Bash / zsh ) verwenden, um eine Datei im laufenden Betrieb zu erstellen, und diese dann als Eingabe für den nächsten Prozess in der Pipelinekette verwenden.
Ich habe beispielsweise versucht, die JSON-Ausgabe von cURL mit
jq
und zu analysierenless
, habe aber denFailed writing body
Fehler erhalten.Als ich es mit Prozessersetzung umgeschrieben habe, hat es funktioniert!
Hinweis:
jq
Verwendet das zweite Argument, um eine Eingabedatei anzugebenBonus: Wenn Sie mit
jq
wie ich und wollen die kolorierte Ausgabe halten inless
, verwenden Sie die folgende Befehlszeile statt:(Dank Kowaru für ihre Erklärung , warum
Failed writing body
auftreten wurde. Doch ihre Lösung mittac
zweimal tat für mich nicht. Ich wollte auch eine Lösung finden , die besser für große Dateien und versucht würden skalieren die anderen Fragen als Kommentare bemerkt zu vermeiden auf diese Antwort.)quelle