cURL이 왜“(23) 본문 쓰기 실패”오류를 반환합니까?


152

단일 도구로 작동합니다.

curl "someURL"
curl -o - "someURL"

그러나 파이프 라인에서는 작동하지 않습니다.

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

다음을 반환합니다.

(23) Failed writing body

cURL 출력 파이핑의 문제점은 무엇입니까? 전체 cURL 출력을 버퍼링하고 처리하는 방법은 무엇입니까?


1
나를 위해 버퍼링 할 필요가 없습니다.
hek2mgl

1
파이프 라인에서도 작동합니까?curl 'http://www.multitran.ru/c/m.exe?CL=1&s=hello&l1=1' | tr -d '\n'
static

1
osx 태그를 추가했습니다. 불행히도 나는 이것을 도울 수 없다. 나는 리눅스를 사용하고있다
hek2mgl

1
문제는 페이지 인코딩 (사이 클릭, win-1251)이었습니다. 따라서 사용해야합니다iconv -f ...
정적

5
또 다른 힌트와 마찬가지로 : 디스크가 가득 차서 광산이 실패했습니다.
빈스 바르가

답변:


113

파이프 된 프로그램 (예 : grep)이 전체 페이지 쓰기를 마치기 전에 이전 프로그램이 읽기 파이프를 닫을 때 발생합니다.

에서 curl "url" | grep -qs foogrep이 원하는 것을 갖 자마자 curl에서 읽기 스트림을 닫습니다. cURL은이를 예상하지 않으며 "실체 쓰기 실패"오류를 발생시킵니다.

해결 방법은 다음 프로그램으로 보내기 전에 항상 전체 페이지를 읽는 중개 프로그램을 통해 스트림을 파이프하는 것입니다.

예 :

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

tac전체 입력 페이지를 읽고 행 순서를 반대로하는 간단한 Unix 프로그램입니다 (따라서 두 번 실행 함). 마지막 줄을 찾으려면 전체 입력을 읽어야하므로 cURL이 완료 될 때까지 grep에 아무것도 출력하지 않습니다. Grep은 찾고있는 내용이있을 때 여전히 읽기 스트림을 닫지 만 오류에 영향을 미치지 않는 tac에만 영향을 미칩니다.


5
cat한 번만 통과 하면 안될까요? 적어도 나를 위해 문제를 해결하십시오.
benvd

5
아니요. 작은 문서에는 도움이 될 수 있지만 너무 커서 버퍼에 맞지 않을 때는 오류가 다시 나타납니다 -s. 필요하지 않은 경우 모든 오류 메시지 (및 진행)를 무음 처리 하는 데 사용할 수 있습니다.
Kaworu 2016 년

9
tac|tac입력 바꿈으로 끝나지 않는 경우, 입력을 변경하거나 예를 위해 printf a\\nb\\nc|tac|tac인쇄 a\ncb어디에 \n줄 바꿈된다. sponge /dev/stdout대신 사용할 수 있습니다 . 또 다른 옵션은 printf %s\\n "$(cat)"이지만 입력에 Zsh 이외의 쉘에 널 바이트가 포함 된 경우 널 바이트를 건너 뛰거나 첫 번째 널 바이트 이후에 읽기를 중지합니다.
nisetama

문서에서 : CURLE_WRITE_ERROR (23) 수신 된 데이터를 로컬 파일에 쓸 때 오류가 발생했거나 쓰기 콜백에서 libcurl로 오류가 리턴되었습니다. curl.haxx.se/libcurl/c/libcurl-errors.html
Jordan Stewart

3
이 문제를 설명하기 때문에, 허용 대답해야 더 없기 때문에 altought이 할 수있는 솔루션을 제공하지 않습니다 tac맥 OS에 명령
도미니크 부커

48

완전성과 향후 검색을 위해 :

cURL이 버퍼를 관리하는 방식과 관련하여 버퍼는 -N 옵션으로 출력 스트림을 비활성화합니다.

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


8
그것은 같은 오류가 발생 curl -s https://raw.githubusercontent.com/hermitdave/FrequencyWords/master/content/2016/ro/ro_50k.txt | head -20하지 않고 작동했습니다 -s.
Dan Dascalescu

24

-o(출력 파일) 옵션을 사용하는 경우 다른 가능성 이 있습니다. 대상 디렉토리가 없습니다.

예. 가지고 -o /tmp/download/abc.txt있고 / tmp / download가없는 경우

따라서, 필요한 디렉토리가 생성되도록 / 사전 존재, 사용 --create-dirs옵션을뿐만 아니라 - o필요한 경우


2
고마워, --create-dirs는 가장 특이한 상황에서 나를 위해 이것을 해결했으며, 무엇이 잘못되었는지 알 수 없었지만 이것이 티켓이었습니다!
rfay

1
비슷한 경우에 나에게 일어난 일입니다. 출력에 변수 $ out을 선언하는 것을 잊었습니다. 고마워, 마이크
Mincong Huang

8

인코딩 문제였습니다. Iconv는 문제를 해결합니다

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

8

-o옵션 을 사용하는 대신이 작업을 수행 할 수 있습니다 .

curl [url] > [file]


파이프를 사용하지 않고 파일 시스템에 대한 모든 작업을 수행합니까? 컬의 출력을 파이프와 함께 사용하고 싶었습니다.
정적

6

나는 같은 오류가 있었지만 다른 이유에서 왔습니다. 내 경우에는 1GB 공간의 (tmpfs) 파티션이 있었고 마침내 해당 파티션의 모든 메모리채운 큰 파일을 다운로드하고 있었고 동일한 오류가 발생했습니다.


5

필자의 경우 서버에 디스크 공간이 부족합니다.

그것을 확인하십시오 df -k .

https://stackoverflow.com/a/28879552/336694tac 에서 설명한 것처럼 두 번의 파이핑을 시도했을 때 디스크 공간이 부족하다는 경고를 받았습니다 . 오류 메시지가 표시되었습니다 write error: No space left on device.


컨테이너 내의 디스크 공간이 부족하여 동일한 오류가 발생했습니다. 동일한 문제가 발생하는 다른 사용자도 컨테이너 내의 공간을 정리할 수 있습니다.docker system prune
Dave

2

우분투에 니스 캐시를 설치하는 동안이 오류 메시지가 발생했습니다. 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

비슷한 것을 시도 source <( curl -sS $url )하고 (23) Failed writing body오류가 발생하면 프로세스 대체 소스가 작동하지 않기 때문입니다 bash 3.2(macOS의 기본값).

대신이 해결 방법을 사용할 수 있습니다.

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

0

저에게는 허가 문제였습니다. Docker 실행은 사용자 프로필로 호출되지만 root는 컨테이너 내부의 사용자입니다. 해결책은 root뿐만 아니라 모든 사용자에게 쓰기 권한이 있기 때문에 curl을 / tmp에 작성하는 것이 었습니다.

-o 옵션을 사용했습니다.

-o / tmp / file_to_download


-1

Bash 및 zsh (및 다른 쉘)에서는 프로세스 대체 ( Bash / zsh )를 사용하여 파일을 즉시 작성한 후 파이프 라인 체인의 다음 프로세스에 대한 입력으로 사용할 수 있습니다.

예를 들어 jqand를 사용하여 cURL에서 JSON 출력을 구문 분석하려고 less했지만 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, 대신 다음 명령 줄을 사용하십시오

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

( 발생 했는지 에 대한 설명에 대해 Kowaru 에게 감사합니다 . 그러나 두 번 사용하는 솔루션은 저에게 효과적이지 않습니다. 또한 대용량 파일에 대해 더 나은 확장 성을 제공하고 의견으로 언급 된 다른 문제를 피하려는 솔루션을 찾고 싶었습니다. 그 대답에.) Failed writing bodytac

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.