Funciona bien como una sola herramienta:
curl "someURL"
curl -o - "someURL"
pero no funciona en una tubería:
curl "someURL" | tr -d '\n'
curl -o - "someURL" | tr -d '\n'
vuelve:
(23) Failed writing body
¿Cuál es el problema con la tubería de salida de cURL? ¿Cómo almacenar en búfer toda la salida de cURL y luego manejarla?
curl 'http://www.multitran.ru/c/m.exe?CL=1&s=hello&l1=1' | tr -d '\n'
iconv -f ...
Respuestas:
Esto sucede cuando un programa canalizado (por ejemplo, grep) cierra la canalización de lectura antes de que el programa anterior termine de escribir toda la página.
En
curl "url" | grep -qs foo
, tan pronto como grep tenga lo que quiere, cerrará la secuencia de lectura de curl. cURL no espera esto y emite el error "Error al escribir el cuerpo".Una solución alternativa es canalizar la transmisión a través de un programa intermediario que siempre lee toda la página antes de pasarla al siguiente programa.
P.ej
tac
es un programa simple de Unix que lee toda la página de entrada e invierte el orden de las líneas (por lo tanto, lo ejecutamos dos veces). Debido a que tiene que leer toda la entrada para encontrar la última línea, no generará nada para grep hasta que cURL haya terminado. Grep seguirá cerrando el flujo de lectura cuando tenga lo que está buscando, pero solo afectará a tac, que no emite un error.fuente
cat
una vez? Resuelve el problema para mí, al menos.-s
para silenciar todos los mensajes de error (y progreso) si no los necesita.tac|tac
cambia la entrada si la entrada no termina con un salto de línea o, por ejemplo,printf a\\nb\\nc|tac|tac
imprimea\ncb
dónde\n
hay un salto de línea. Puedes usarsponge /dev/stdout
en su lugar. Otra opción esprintf %s\\n "$(cat)"
, pero cuando la entrada contiene bytes nulos en shells distintos de Zsh, eso omite los bytes nulos o deja de leer después del primer byte nulo.tac
comando en macOSPara completar y futuras búsquedas:
Es una cuestión de cómo cURL administra el búfer, el búfer deshabilita el flujo de salida con la opción -N.
Ejemplo:
curl -s -N "URL" | grep -q Welcome
fuente
curl -s https://raw.githubusercontent.com/hermitdave/FrequencyWords/master/content/2016/ro/ro_50k.txt | head -20
(sin que-s
me salga el mismo error).Otra posibilidad, si usa la
-o
opción (archivo de salida), el directorio de destino no existe.p.ej. si tiene
-o /tmp/download/abc.txt
y / tmp / download no existe.Por lo tanto, asegúrese de que los directorios necesarios se creen / existan de antemano, use la
--create-dirs
opción y,o
si es necesariofuente
Entonces fue un problema de codificación. Iconv resuelve el problema
fuente
Puede hacer esto en lugar de usar la
-o
opción:curl [url] > [file]
fuente
Tuve el mismo error pero por diferentes razones. En mi caso, tenía una partición (tmpfs) con solo 1GB de espacio y estaba descargando un archivo grande que finalmente llenó toda la memoria de esa partición y obtuve el mismo error que usted.
fuente
El servidor se quedó sin espacio en disco, en mi caso.
Compruébalo con
df -k .
Me alertaron de la falta de espacio en disco cuando intenté pasar
tac
dos veces, como se describe en una de las otras respuestas: https://stackoverflow.com/a/28879552/336694 . Me mostró el mensaje de errorwrite error: No space left on device
.fuente
docker system prune
El error se encuentra al ejecutar el comando como root
curl -L https://packagecloud.io/varnishcache/varnish5/gpgkey | apt-key add -
la solución es correr
apt-key add
como no rootfuente
Si está intentando algo similar
source <( curl -sS $url )
y obtiene el(23) Failed writing body
error, es porque el abastecimiento de una sustitución de proceso no funcionabash 3.2
(el valor predeterminado para macOS).En su lugar, puede usar esta solución alternativa.
fuente
Para mí, fue un problema de permiso. Docker run se llama con un perfil de usuario, pero root es el usuario dentro del contenedor. La solución fue hacer curl write to / tmp ya que tiene permiso de escritura para todos los usuarios, no solo root.
Usé la opción -o.
-o / tmp / file_to_download
fuente
En Bash y zsh (y quizás otros shells), puede usar la sustitución de procesos ( Bash / zsh ) para crear un archivo sobre la marcha, y luego usarlo como entrada para el siguiente proceso en la cadena de canalización.
Por ejemplo, estaba tratando de analizar la salida JSON de cURL usando
jq
yless
, pero recibía elFailed writing body
error.Cuando lo reescribí usando la sustitución del proceso, ¡funcionó!
Nota:
jq
usa su segundo argumento para especificar un archivo de entradaBono: Si usted está utilizando
jq
como yo y quiere mantener la salida coloreada enless
, utilice la siguiente línea de comandos en su lugar:(Gracias a Kowaru por su explicación de por qué
Failed writing body
estaba ocurriendo. Sin embargo, su solución de usartac
dos veces no funcionó para mí. También quería encontrar una solución que escalara mejor para archivos grandes y trata de evitar los otros problemas señalados como comentarios a esa respuesta.)fuente