Ini berfungsi ok sebagai alat tunggal:
curl "someURL"
curl -o - "someURL"
tapi itu tidak bekerja di saluran pipa:
curl "someURL" | tr -d '\n'
curl -o - "someURL" | tr -d '\n'
mengembalikan:
(23) Failed writing body
Apa masalah dengan piping output CURL? Bagaimana cara buffer seluruh output CURL dan kemudian menanganinya?
curl 'http://www.multitran.ru/c/m.exe?CL=1&s=hello&l1=1' | tr -d '\n'
iconv -f ...
Jawaban:
Ini terjadi ketika program yang disalurkan (misalnya grep) menutup pipa baca sebelum program sebelumnya selesai menulis seluruh halaman.
Di
curl "url" | grep -qs foo
, segera setelah grep memiliki apa yang diinginkannya, ia akan menutup aliran baca dari curl. cURL tidak mengharapkan ini dan memancarkan kesalahan "Failed writing body".Solusinya adalah menyalurkan aliran melalui program perantara yang selalu membaca seluruh halaman sebelum memasukkannya ke program berikutnya.
Misalnya
tac
adalah program Unix sederhana yang membaca seluruh halaman input dan membalik urutan baris (karenanya kami menjalankannya dua kali). Karena harus membaca seluruh input untuk menemukan baris terakhir, itu tidak akan menampilkan apa pun untuk grep sampai cURL selesai. Grep masih akan menutup aliran baca ketika memiliki apa yang dicari, tetapi hanya akan memengaruhi tac, yang tidak memunculkan kesalahan.sumber
cat
sekali saja? Setidaknya, selesaikan masalah ini untuk saya.-s
untuk membungkam semua pesan kesalahan (dan kemajuan) jika Anda tidak membutuhkannya.tac|tac
mengubah input jika input tidak diakhiri dengan linefeed, atau misalnyaprintf a\\nb\\nc|tac|tac
mencetak dia\ncb
mana\n
linefeed. Anda bisa menggunakannyasponge /dev/stdout
. Pilihan lain adalahprintf %s\\n "$(cat)"
, tetapi ketika input berisi byte kosong di shell selain Zsh, yang melewatkan byte nol atau berhenti membaca setelah byte nol pertama.tac
perintah pada macOSUntuk kelengkapan dan pencarian di masa mendatang:
Ini masalah bagaimana CURL mengelola buffer, buffer menonaktifkan aliran output dengan opsi -N.
Contoh:
curl -s -N "URL" | grep -q Welcome
sumber
curl -s https://raw.githubusercontent.com/hermitdave/FrequencyWords/master/content/2016/ro/ro_50k.txt | head -20
(tanpa-s
saya mendapatkan kesalahan yang sama).Kemungkinan lain, jika menggunakan opsi
-o
(file output) - direktori tujuan tidak ada.misalnya. jika sudah
-o /tmp/download/abc.txt
dan / tmp / unduh tidak ada.Oleh karena itu, pastikan direktori yang diperlukan dibuat / ada sebelumnya, gunakan
--create-dirs
opsi dan -o
jika perlusumber
Jadi itu masalah pengkodean. Iconv memecahkan masalah
sumber
Anda dapat melakukan ini alih-alih menggunakan
-o
opsi:curl [url] > [file]
sumber
Saya memiliki kesalahan yang sama tetapi dari alasan berbeda. Dalam kasus saya, saya memiliki (tmpfs) partisi dengan hanya 1GB ruang dan saya mengunduh file besar yang akhirnya mengisi semua memori pada partisi itu dan saya mendapatkan kesalahan yang sama seperti Anda.
sumber
Server kehabisan ruang disk, dalam kasus saya.
Periksa dengan
df -k .
Saya diberitahu tentang kurangnya ruang disk ketika saya mencoba memipakan
tac
dua kali, seperti yang dijelaskan dalam salah satu jawaban lain: https://stackoverflow.com/a/28879552/336694 . Itu menunjukkan kepada saya pesan kesalahanwrite error: No space left on device
.sumber
docker system prune
Bug ini ditemui saat menjalankan perintah sebagai root
curl -L https://packagecloud.io/varnishcache/varnish5/gpgkey | apt-key add -
solusinya adalah berjalan
apt-key add
sebagai non rootsumber
Jika Anda mencoba sesuatu yang mirip seperti
source <( curl -sS $url )
dan mendapatkan(23) Failed writing body
kesalahan, itu karena sumber substitusi proses tidak berfungsibash 3.2
(default untuk macOS).Sebagai gantinya, Anda dapat menggunakan solusi ini.
sumber
Bagi saya, itu masalah izin. Docker run disebut dengan profil pengguna tetapi root adalah pengguna di dalam wadah. Solusinya adalah membuat curl write ke / tmp karena itu memiliki izin menulis untuk semua pengguna, bukan hanya root.
Saya menggunakan opsi -o.
-o / tmp / file_to_download
sumber
Di Bash dan zsh (dan mungkin cangkang lain), Anda bisa menggunakan subtitusi proses ( Bash / zsh ) untuk membuat file dengan cepat, dan kemudian menggunakannya sebagai input untuk proses selanjutnya dalam rantai pipa.
Sebagai contoh, saya mencoba mengurai output JSON dari cURL menggunakan
jq
danless
, tetapi mendapatkanFailed writing body
kesalahan.Ketika saya menulis ulang menggunakan proses substitusi, itu berhasil!
Catatan:
jq
menggunakan argumen ke-2 untuk menentukan file inputBonus: Jika Anda menggunakan
jq
seperti saya dan ingin menjaga output berwarna diless
, gunakan baris perintah berikut ini sebagai gantinya:(Terima kasih kepada Kowaru untuk penjelasan mereka tentang mengapa
Failed writing body
itu terjadi. Namun, solusi mereka menggunakantac
dua kali tidak bekerja untuk saya. Saya juga ingin menemukan solusi yang dapat meningkatkan skala untuk file besar dan mencoba untuk menghindari masalah lain yang dicatat sebagai komentar untuk jawaban itu.)sumber