Estoy leyendo un par de libros sobre scripts de bash y me cuesta entender las citas adecuadas y el uso de IFS
. Quizás alguien pueda ayudarme con un pequeño ejemplo que involucra nombres de archivo con comillas. Al hacer esto desde una línea de comando, esto funciona para imprimir los nombres de archivo correctamente, incluso si incluyen espacios:
set - *
for i in "$@"; do echo $i; done
Esto no funciona, ya que se rompe en los espacios:
set - `find . -name "*"`
for i in "$@"; do echo $i; done
Ni tampoco:
IFS=$'\0' set - `find . -name "*" -print0`
for i in "$@"; do echo $i; done
Tampoco la combinación que usa IFS=$'\n'
y -print
. ¿Por qué fallan todos estos?
Lo siguiente también falla, pero en este caso se produce un error ("bash: error de sintaxis cerca del token inesperado` do '"). ¿Por qué?
IFS=$'\n' for i in `find . -name "*" -type f`; do echo $i; done
pero esto funciona (observe el ";"):
IFS=$'\n'; for i in `find . -name "*" -type f`; do echo $i; done
y esto falla porque los nombres de archivo no se dividen en absoluto (los for
bucles solo una vez):
IFS=''; for i in `find . -name "*" -type f -print0`; do echo -e "$i\n"; done
Entonces, de nuevo, ¿por qué fallan el primero y el tercero?
Finalmente, ¿estoy en lo cierto al creer que, al configurar IFS
, ''
es lo mismo que $'\0'
? (Probé ambos en el ejemplo anterior). Si es así, ¿por qué aparentemente necesito en $'\n'
lugar de solo \n
?
* Bash es la versión 4.3.42 (1) en Ubuntu Gnome 16.04.
;
después del IFS=...
yo no. Es como el segundo caso en el segundo grupo de 3. La pregunta es, ¿por qué es necesario? Espero que sin el ;
, la modificación de la variable sea temporal, dentro del siguiente comando. No quiero que sea permanente.
IFS=$'\n'; set - `find`;
trabajar pero no IFS=$'\n' set - `find`;
. Una explicación plausible es que en IFS=$'\n' set - `find`;
, find
se sustituye y se tokeniza con IFS actual antes de set
ejecutarse.
IFS=$'\n' set -
encontrar. -name "*" -print`` yfor i in "$@"; do echo $i; done
. Definitivamente no funciona.