为什么cURL返回错误"(23) Failed writing body"?
cURL为什么会返回错误“(23)写入body失败”?
当一个管道程序(例如grep)在前一个程序完成写入整个页面之前关闭读取管道时,就会出现这个问题。
在“curl“url” | grep -qs foo”中,一旦grep得到它想要的内容,它就会关闭来自curl的读取流。cURL不希望出现这种情况,所以会出现“写入body失败”的错误。
解决方法是将流通过一个中间程序进行管道传输,该程序总是在将页面传递给下一个程序之前读取整个页面。
例如:
curl “url” | tac | tac | grep -qs foo
tac是一个简单的Unix程序,它读取整个输入页面并反转行的顺序(因此我们运行它两次)。因为它必须读取整个输入以找到最后一行,所以在cURL完成之前它不会向grep输出任何内容。当grep得到它想要的内容时,它仍然会关闭读取流,但这只会影响到tac,而不会引发错误。
你不可以简单地通过cat来进行管道传输吗?至少对我来说可以解决问题。
不行。对于太大而无法适应缓冲区的文档,cat使用的错误将重新出现。如果你不需要错误消息(和进度),可以使用-s来静音。
tac | tac会改变输入,如果输入不以换行符结束,或者例如printf a\\nb\\nc | tac | tac会打印a\ncb,其中\n是换行符。你可以使用sponge /dev/stdout来代替。另一个选项是printf %s\\n "$(cat)",但是当输入在除了Zsh之外的shell中包含空字节时,它要么跳过空字节,要么在第一个空字节后停止读取。
从文档中可以看到:CURLE_WRITE_ERROR(23)在将接收到的数据写入本地文件时发生错误,或者从写回调函数返回错误给libcurl。
这是被接受的答案,因为它解释了问题,尽管它没有提供有效的解决方案,因为macOS上没有tac命令。
我只是忽略stderr并将其发送到null:curl “url” 2>/dev/null | grep
这看起来很丑陋,但对于调查来说很有用;它可以让你看到真正的错误,比如你正在管道传输的命令没有安装。然后你可以移除tac|tac。