Funciona bem como uma única ferramenta:
curl "someURL"
curl -o - "someURL"
mas não funciona em um pipeline:
curl "someURL" | tr -d '\n'
curl -o - "someURL" | tr -d '\n'
retorna:
(23) Failed writing body
Qual é o problema de canalizar a saída cURL? Como armazenar em buffer toda a saída cURL e depois lidar com isso?
curl 'http://www.multitran.ru/c/m.exe?CL=1&s=hello&l1=1' | tr -d '\n'
iconv -f ...
Respostas:
Isso acontece quando um programa canalizado (por exemplo, grep) fecha o canal de leitura antes que o programa anterior termine de escrever a página inteira.
Em
curl "url" | grep -qs foo
, assim que o grep tiver o que deseja, ele fechará o fluxo de leitura de curl. O cURL não espera isso e emite o erro "Falha na gravação do corpo".Uma solução alternativa é canalizar o fluxo por meio de um programa intermediário que sempre lê a página inteira antes de enviá-la para o próximo programa.
Por exemplo
tac
é um programa Unix simples que lê toda a página de entrada e inverte a ordem das linhas (portanto, executamos duas vezes). Como ele precisa ler toda a entrada para encontrar a última linha, ele não produzirá nada para grep até que cURL seja concluído. O Grep ainda fechará o fluxo de leitura quando tiver o que está procurando, mas afetará apenas o tac, que não emite um erro.fonte
cat
uma vez? Resolve o problema para mim, pelo menos.-s
silenciar todas as mensagens de erro (e avançar) se não precisar delas.tac|tac
altera a entrada se a entrada não terminar com um avanço de linha ou, por exemplo,printf a\\nb\\nc|tac|tac
imprimira\ncb
onde\n
está um avanço de linha. Você pode usar em seusponge /dev/stdout
lugar. Outra opção éprintf %s\\n "$(cat)"
, mas quando a entrada contém bytes nulos em shells diferentes de Zsh, isso ignora os bytes nulos ou para de ler após o primeiro byte nulo.tac
comando no MacOSPara pesquisas completas e futuras:
É uma questão de como o cURL gerencia o buffer, o buffer desativa o fluxo de saída com a opção -N.
Exemplo:
curl -s -N "URL" | grep -q Welcome
fonte
curl -s https://raw.githubusercontent.com/hermitdave/FrequencyWords/master/content/2016/ro/ro_50k.txt | head -20
(sem-s
eu receber o mesmo erro).Outra possibilidade, se usar o
-o
(arquivo de saída) - o diretório de destino não existe.por exemplo. se você possui
-o /tmp/download/abc.txt
e / tmp / download não existe.Portanto, verifique se todos os diretórios necessários foram criados / existentes com antecedência, use a
--create-dirs
opção e -o
se necessáriofonte
Portanto, era um problema de codificação. Iconv resolve o problema
fonte
Você pode fazer isso em vez de usar a
-o
opção:curl [url] > [file]
fonte
Eu tive o mesmo erro, mas por outro motivo. No meu caso, eu tinha a partição (tmpfs) com apenas 1 GB de espaço e estava baixando um arquivo grande que finalmente preencheu toda a memória dessa partição e obtive o mesmo erro que você.
fonte
O servidor ficou sem espaço em disco, no meu caso.
Verifique com
df -k .
Fui alertado sobre a falta de espaço em disco quando tentei passar por
tac
duas vezes, conforme descrito em uma das outras respostas: https://stackoverflow.com/a/28879552/336694 . Ele me mostrou a mensagem de errowrite error: No space left on device
.fonte
docker system prune
O erro é encontrado ao executar o comando como root
curl -L https://packagecloud.io/varnishcache/varnish5/gpgkey | apt-key add -
a solução é executar
apt-key add
como não raizfonte
Se você está tentando algo semelhante
source <( curl -sS $url )
e obtendo o(23) Failed writing body
erro, é porque a aquisição de uma substituição de processo não funciona embash 3.2
(o padrão para o macOS).Em vez disso, você pode usar esta solução alternativa.
fonte
Para mim, era questão de permissão. A execução do Docker é chamada com um perfil de usuário, mas root é o usuário dentro do contêiner. A solução foi fazer a gravação curl em / tmp, pois ela tem permissão de gravação para todos os usuários, não apenas para raiz.
Eu usei a opção -o.
-o / tmp / file_to_download
fonte
No Bash e no zsh (e talvez em outros shells), você pode usar a substituição de processo ( Bash / zsh ) para criar um arquivo rapidamente e, em seguida, usá-lo como entrada para o próximo processo na cadeia de pipeline.
Por exemplo, eu estava tentando analisar a saída JSON do cURL usando
jq
eless
, mas estava obtendo oFailed writing body
erro.Quando eu o reescrevi usando substituição de processo, funcionou!
Nota:
jq
usa seu segundo argumento para especificar um arquivo de entradaBônus: Se você estiver usando
jq
como eu e quer manter a saída colorizado emless
, use a seguinte linha de comando em vez disso:(Obrigado a Kowaru pela explicação sobre o motivo da
Failed writing body
ocorrência. No entanto, a solução de usartac
duas vezes não funcionou para mim. Eu também queria encontrar uma solução que fosse melhor dimensionada para arquivos grandes e tente evitar os outros problemas mencionados como comentários. para essa resposta.)fonte