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.cat
s juntos, solo para molestar a los fanáticos de UUOCcat
solo 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:read
interpreta\
como un personaje de escape; useread -r
para apagar esto.read
se divide en palabras en caracteres en$IFS
; establecerIFS
en 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= read
usa 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:echo
procesos escapan de barra invertida. (En bash, depende de si laxpg_echo
opción está configurada).-n
o-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 -n
serí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 quenoclobber
está 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
\0
nulos 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