Tengo una función bash que toma un archivo como parámetro, verifica que el archivo existe y luego escribe cualquier cosa que salga del stdin en el archivo. La solución ingenua funciona bien para el texto, pero estoy teniendo problemas con datos binarios arbitrarios.
echo -n '' >| "$file" #Truncate the file
while read lines
do # Is there a better way to do this? I would like one...
echo $lines >> "$file"
done

> $file. Esto solo funciona como lo primero que busca stdin en el script de shell principal. Básicamente, todo el código de David se puede reducir a un solo personaje, pero creo quecat -es más elegante y menos problemático porque se entiende a simple vista.cats juntos, solo para molestar a los fanáticos de UUOCcatsolo para que las personas que insisten en usarlo necesariamente tengan que hacer gimnasia mental para leer el código. Las tuberías con nombre también son buenos objetivos.Para leer un archivo de texto literalmente, no use plain
read, que procesa la salida de dos maneras:readinterpreta\como un personaje de escape; useread -rpara apagar esto.readse divide en palabras en caracteres en$IFS; establecerIFSen una cadena vacía para desactivar esto.El idioma habitual para procesar un archivo de texto línea por línea es
Para obtener una explicación de este idioma, vea ¿Por qué se
while IFS= readusa con tanta frecuencia, en lugar deIFS=; while read..? .Para escribir una cadena literalmente, no use simplemente plain
echo, que procesa la cadena de dos maneras:echoprocesos escapan de barra invertida. (En bash, depende de si laxpg_echoopción está configurada).-no-e(el conjunto exacto depende del shell).Una forma portátil de imprimir una cadena literalmente es con
printf. (No hay mejor manera en bash, a menos que sepa que su entrada no parece una opciónecho). Use el primer formulario para imprimir la cadena exacta y el segundo formulario si desea agregar una nueva línea.Esto solo es adecuado para procesar texto , porque:
No puede procesar datos binarios en el shell, pero las versiones modernas de utilidades en la mayoría de los dispositivos pueden hacer frente a datos arbitrarios. Para pasar toda la entrada a la salida, use
cat. Ir por una tangenteecho -n ''es una forma complicada y no portátil de no hacer nada;echo -nsería igual de bueno (o no dependiendo del shell), y:es más simple y totalmente portátil.o, más simple,
En un script, generalmente no necesita usarlo
>|ya quenoclobberestá desactivado de manera predeterminada.fuente
Esto hará exactamente lo que quieres:
Sin embargo, tenga en cuenta el uso de memoria. Esto lee la entrada de forma nula delimitada.
Si no hay bytes
\0nulos en la entrada, bash primero tendrá que leer todo el contenido de la entrada en la memoria y luego emitirlo.Con respecto a su paso truncado:
un mucho más simple y equivalente es:
fuente