为什么CURL返回和错误(23)写入正文失败?

时间:2013-05-23 00:16:11

标签: macos bash curl osx-lion pipe

它作为一个工具正常工作:

curl "someURL"
curl -o - "someURL"

但它在管道中不起作用:

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

它返回:

(23) Failed writing body

卷曲输出管道有什么问题?如何缓冲整个curl输出然后处理它?<​​/ p>

13 个答案:

答案 0 :(得分:86)

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

curl "url" | grep -qs foo中,只要grep具有它想要的内容,它就会关闭curl的读取流。 cURL不期望这样,并发出“失败的写作正文”错误。

解决方法是通过中间程序管道流,该程序在将其提供给下一个程序之前始终读取整个页面。

E.g。

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

tac是一个简单的Unix程序,它读取整个输入页面并反转行顺序(因此我们运行它两次)。因为它必须读取整个输入才能找到最后一行,所以在cURL完成之前它不会向grep输出任何内容。当Grep具有它正在寻找的内容时,Grep仍会关闭读取流,但它只会影响tac,这不会发出错误。

答案 1 :(得分:24)

(完整性和未来搜索) 这是CURL如何管理缓冲区的问题,缓冲区使用-N选项禁用输出流。

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

答案 2 :(得分:9)

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

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

答案 3 :(得分:9)

您可以执行此操作,而不是使用-o选项:

curl [url] > [file]

答案 4 :(得分:8)

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

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

因此,请确保事先创建/存在所有必需的目录,并在必要时使用--create-dirs选项以及 - o

答案 5 :(得分:6)

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

答案 6 :(得分:1)

  

我在尝试在ubuntu上安装varnish cache时遇到此错误消息。谷歌搜索让我在这里找到错误(23) Failed writing body,因此发布了一个对我有用的解决方案。

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

运行命令时遇到错误

解决方案是以非root身份运行apt-key add

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

答案 7 :(得分:1)

在我的情况下,服务器的磁盘空间不足。

使用df -k .

检查

当我尝试两次通过tac时,我被警告没有磁盘空间,如其他答案之一所述:https://stackoverflow.com/a/28879552/336694。它向我显示了错误消息write error: No space left on device

答案 8 :(得分:1)

如果您尝试使用类似source <( curl -sS $url )之类的方法并遇到(23) Failed writing body错误,那是因为在bash 3.2(macOS的默认设置)中,无法找到进程替代项。 / p>

相反,您可以使用此替代方法。

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

答案 9 :(得分:1)

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

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

以上查询需要使用root权限执行。

以下列方式编写它为我解决了这个问题:

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

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

答案 10 :(得分:0)

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

我使用-o选项。

-o / tmp / file_to_download

答案 11 :(得分:0)

就我而言,我正在做: import {Button, Dialog} from "@material-ui/core"; . . return ( <div> <Button>Submit</Button> <Dialog></Dialog> </div> )

使用curl <blabla> | jq | grep <blibli>可以工作:jq .

答案 12 :(得分:-2)

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

例如,我试图使用jqless解析来自cURL的JSON输出,但出现Failed writing body错误。

# 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,并且想在less中使用keep the colorized output,请改用以下命令行:

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

(感谢Kowaru对为什么发生 Failed writing body的解释。但是,他们两次使用tac的解决方案对我不起作用。我还想找到一种解决方案,该解决方案可以更好地适应大型文件,并尝试避免在回答该注释时指出其他问题。)