作为一个单独的工具,它工作得很好:

curl "someURL"
curl -o - "someURL"

但这在流水线上行不通:

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

它返回:

(23) Failed writing body

管道cURL输出的问题是什么?如何缓冲整个cURL输出,然后处理它?


所以这是编码的问题。Iconv解决了这个问题

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

你可以这样做,而不是使用-o选项:

Curl [url] >[文件]


当管道程序(例如grep)在前一个程序完成整个页面的写入之前关闭读管道时,就会发生这种情况。

在curl "url" | grep -qs foo中,一旦grep得到它想要的,它就会关闭curl的读取流。cURL没有预料到这一点,并发出“写入正文失败”错误。

一种解决方法是将流通过中间程序输送,该程序总是在将其提供给下一个程序之前读取整个页面。

E.g.

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

tac是一个简单的Unix程序,它读取整个输入页并颠倒行序(因此我们运行了两次)。因为它必须读取整个输入以找到最后一行,所以在cURL完成之前它不会向grep输出任何内容。当Grep得到它要找的东西时,它仍然会关闭读流,但它只会影响tac,而tac不会发出错误。


对于完整性和将来的搜索:

这取决于cURL如何管理缓冲区,缓冲区使用-N选项禁用输出流。

例子: curl -s -N "URL" | grep -q欢迎


我犯了同样的错误,但原因不同。在我的情况下,我有(tmpfs)分区只有1GB空间,我正在下载大文件,最终填满了该分区上的所有内存,我得到了和你一样的错误。


另一种可能是,如果使用-o(输出文件)选项,目标目录不存在。

如。如果你有-o /tmp/download/abc.txt且/tmp/download不存在。

因此,确保任何需要的目录都是预先创建/存在的,使用——create-dirs选项,必要时使用-o


我在ubuntu上安装清漆缓存时遇到了这个错误信息。谷歌搜索让我在这里的错误(23)失败的写作主体,因此张贴一个解决方案,为我工作。

在以根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 -

在我的情况下,服务器耗尽了磁盘空间。

用df -k检查它。

当我尝试两次通过tac进行管道处理时,我被提醒磁盘空间不足,如另一个答案:https://stackoverflow.com/a/28879552/336694中所描述的那样。它向我显示了错误消息写错误:设备上没有剩余空间。


对我来说,这是许可问题。Docker运行是使用用户配置文件调用的,但root是容器内的用户。解决方案是让curl写入/tmp,因为它对所有用户都有写权限,而不仅仅是根用户。

我使用了-o选项。

- o / tmp / file_to_download


如果你正在尝试类似source <(curl -sS $url)这样的东西,并得到(23)Failed writing body错误,这是因为在bash 3.2 (macOS的默认)中,源进程替换不起作用。

相反,您可以使用这个解决方案。

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

在Bash和zsh(也许还有其他shell)中,您可以使用进程替换(Bash/zsh)动态地创建一个文件,然后将该文件作为管道链中下一个进程的输入。

例如,我试图用jq和更少的方法从cURL解析JSON输出,但得到了失败的写入正文错误。

# Note: this does NOT work
curl https://gitlab.com/api/v4/projects/ | jq | less

当我用过程替换重写它时,它起作用了!

# this works!
jq "" <(curl https://gitlab.com/api/v4/projects/) | less

注意:jq使用它的第二个参数指定一个输入文件

额外的好处:如果你像我一样使用jq,并且想让彩色输出更少,可以使用下面的命令行:

jq -C "" <(curl https://gitlab.com/api/v4/projects/) | less -r

(感谢Kowaru解释了为什么会出现失败的写作体。然而,他们使用两次战术的解决方案对我不起作用。我还想找到一种解决方案,可以更好地扩展大文件,并尽量避免注释中提到的其他问题。)


就我而言,我在做: Curl <blabla> | jq | grep <blibli>

用jq。它工作:curl <blabla> | jq。| grep <blibli>


我在做的时候也遇到了同样的问题:

curl - l https://packagecloud.io/golang-migrate/migrate/gpgkey | apt-key add -

上面的查询需要使用根权限执行。

用下面的方法解决了这个问题:

curl - l https://packagecloud.io/golang-migrate/migrate/gpgkey | sudo apt-key add -

如果在curl之前编写sudo,则会得到Failed writing body错误。


用sudo尝试命令对我有用。例如:

sudo curl -O -k 'https url here'

注意:-O(这是大写o,不是零)& -k https url。


I was getting curl:(23)写作体不及格。后来我注意到我没有足够的空间通过curl下载rpm包,这就是我得到问题的原因。我腾出了一些空间和问题来解决。


我添加了flag -s,它完成了任务。例如:curl -o- s https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash


@Kaworu的解释很棒:https://stackoverflow.com/a/28879552/198219

当管道程序(例如grep)在前一个程序完成整个页面的写入之前关闭读管道时,就会发生这种情况。cURL没有预料到这一点,并发出“写入正文失败”错误。

一种解决方法是将流通过中间程序输送,该程序总是在将其提供给下一个程序之前读取整个页面。

我认为更正确的做法是使用海绵,就像@nisetama在评论中建议的那样:

Curl "url" |海绵| grep -qs foo


我得到这个错误试图使用jq时,我没有安装jq。所以…如果您尝试使用jq,请确保已安装jq。


因为我自己的打字错误,我也有同样的问题:

# fails because of reasons mentioned above
curl -I -fail https://www.google.com | echo $? 
curl: (23) Failed writing body

# success
curl -I -fail https://www.google.com || echo $?