我正在阅读几本关于bash脚本的书,并努力理解正确的引用和使用IFS。也许有人可以帮我一个涉及带引号的文件名的小例子。从命令行执行此操作,即使它们包含空格,也可以正确打印文件名:
set - *
for i in "$@"; do echo $i; done
这不起作用,因为它在空格处断开:
set - `find . -name "*"`
for i in "$@"; do echo $i; done
也不是:
IFS=$'\0' set - `find . -name "*" -print0`
for i in "$@"; do echo $i; done
使用IFS=$'\n'和的组合也不是-print。为什么这些都失败了?
以下也失败了,但在这种情况下它出错(“bash:意外令牌'do'附近的语法错误”)。为什么?
IFS=$'\n' for i in `find . -name "*" -type f`; do echo $i; done
但这有效(注意“;”):
IFS=$'\n'; for i in `find . -name "*" -type f`; do echo $i; done
这会失败,因为文件名根本没有拆分(for循环只有一次):
IFS=''; for i in `find . -name "*" -type f -print0`; do echo -e "$i\n"; done
那么,为什么第一个和第三个失败了?
最后,我认为在设定时IFS,我是否''相同$'\0'?(我在之前的例子中尝试了两种方法。)如果是这样,为什么我显然需要$'\n'而不仅仅是\n?
* Bash是Ubuntu Gnome 16.04中的版本4.3.42(1)。
;后的IFS=... 我不知道。这就像第二组3中的第二个案例。问题是,为什么需要这样做?我希望没有;,变量的修改应该是临时的,在下面的命令中。我不希望它是永久性的。
IFS=$'\n'; set - `find`;工作而不是IFS=$'\n' set - `find`;。一种可能的解释是IFS=$'\n' set - `find`;,find被取代的,并与之前电流IFS记号化set执行。
IFS=$'\n' set -找。-name“*” - print``和for i in "$@"; do echo $i; done。它肯定不起作用。