web-dev-qa-db-ja.com

なぜCURLが返され、エラー(23)本文の書き込みに失敗しましたか?

単一のツールとして大丈夫です:

curl "someURL"
curl -o - "someURL"

しかし、パイプラインでは機能しません:

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

それは返します:

(23) Failed writing body

カール出力のパイピングの問題は何ですか?カール出力全体をバッファリングしてから処理する方法は?

100
static

これは、前のプログラムがページ全体の書き込みを終了する前に、パイプ処理されたプログラム(grepなど)が読み取りパイプを閉じると発生します。

curl "url" | grep -qs fooでは、grepが必要なものを取得するとすぐに、curlからの読み取りストリームを閉じます。 cURLはこれを予期せず、「本文の書き込みに失敗しました」エラーを発行します。

回避策は、次のプログラムにフィードする前に常にページ全体を読み取る中間プログラムにストリームをパイプすることです。

例えば。

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

tacは、入力ページ全体を読み取り、行の順序を逆にする単純なUnixプログラムです(したがって、2回実行します)。最後の行を見つけるために入力全体を読み取る必要があるため、cURLが終了するまでgrepに何も出力しません。 Grepは、探しているものがあれば読み取りストリームを閉じますが、tacにのみ影響し、エラーは発生しません。

87
Kaworu

(完全性と将来の検索のため)CURLがバッファを管理する方法に関係なく、バッファは-Nオプションで出力ストリームを無効にします。

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

26
user5968839

別の可能性として、-o(出力ファイル)オプションを使用する場合-宛先ディレクトリーが存在しません。

例えば。 -o /tmp/download/abc.txtがあり、/ tmp/downloadが存在しない場合。

したがって、必要なディレクトリが事前に作成/存在していることを確認し、必要に応じて--create-dirsオプションと-oを使用します

10
MikeW

そのため、エンコードの問題でした。 Iconvは問題を解決します

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

-oオプションを使用する代わりにこれを行うことができます。

curl [url] > [file]

9
user339827

同じエラーが発生しましたが、理由は異なります。私の場合、1GBのスペースしかない(tmpfs)パーティションがあり、そのパーティションで最終的にすべてのメモリを埋めたの大きなファイルをダウンロードしていたので、同じエラーが発生しました。

6
LLL

buntuにニスキャッシュをインストールしようとしているときにこのエラーメッセージが表示されました。Google検索でエラー(23) Failed writing bodyが表示されたため、解決策が投稿されました。

ルートcurl -L https://packagecloud.io/varnishcache/varnish5/gpgkey | apt-key add -としてコマンドを実行中にバグが発生しました

解決策は、apt-key addを非ルートとして実行することです

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

私の場合、サーバーはディスク容量を使い果たしました。

df -k .で確認してください

他の回答のいずれかで説明されているように、tacを2回パイピングしようとすると、ディスク容量の不足が警告されました: https://stackoverflow.com/a/28879552/336694 。エラーメッセージwrite error: No space left on deviceが表示されました。

1

source <( curl -sS $url )のような類似したものを試して(23) Failed writing bodyエラーを取得している場合、プロセス置換のソースがbash 3.2(macOSのデフォルト)で機能しないためです。

代わりに、この回避策を使用できます。

source /dev/stdin <<<"$( curl -sS $url )"
0
wisbucky

私にとっては、許可の問題でした。 Docker runはユーザープロファイルで呼び出されますが、rootはコンテナー内のユーザーです。解決策は、rootだけでなくすべてのユーザーに書き込み許可があるので、curlに/ tmpに書き込むことでした。

-oオプションを使用しました。

-o/tmp/file_to_download

0
lallolu