我在阅读IFS 上的博客时看到了这一行:
for i in $(<test.txt)
并认为$(<test.txt)
将文件内容打印到 STDOUT。我可能在这方面错了,但出于好奇,我试图在 shell 上做到这一点。所以拿起一个名为array
具有随机数据的随机文件和
首先做了一个cat array
给我的:
amit@C0deDaedalus:~/test$
amit@C0deDaedalus:~/test$ cat array
1) Ottawa Canada 345644
2) Kabul Afghanistan 667345
3) Paris France 214423
4) Moscow Russia 128793
5) Delhi India 142894
然后这样做$(<array)
给了我这个:
amit@C0deDaedalus:~/test$ $(<array)
1) Ottawa Ca: command not found
我只知道它<
用于输入重定向,但没有得到 shell 在这里解释为命令的确切内容。
任何人都可以在 shell 中解释这个奇怪的输出背后的概念吗?
更新 :-
在运行set -x
时它给出了这个:
amit@C0deDaedalus:~/test$ $(<array)
+ '1)' Ottawa Canada 345644 '2)' Kabul Afghanistan 667345 '3)' Paris France 214423 '4)' Moscow Russia 128793 '5)' Delhi India 142894
+ '[' -x /usr/lib/command-not-found ']'
+ /usr/lib/command-not-found -- '1)'
1): command not found
+ return 127
amit@C0deDaedalus:~/test$
该
$(command)
语法command
在子 shell 环境中执行,并将其自身替换为command
. 而且,正如 Bash Manual 所说,$(< file)
它只是一个更快的等价物$(cat file)
(不过,这不是 POSIX 功能)。因此,当您运行 时
$(<array)
,Bash 会执行该替换,然后它将第一个字段用作命令的名称,将其余字段用作命令的参数:我没有任何
1)
命令/功能,因此它会打印一条错误消息。但是在您的特定情况下,您可能会收到不同的错误消息,因为您修改了 IFS 变量:
编辑 1
我的猜测是你
IFS
被某种方式修改了,所以这就是为什么你的 shell 试图执行1) Ottawa Ca
而不是1)
. 毕竟,您正在阅读与IFS
相关的文章。IFS
如果您最终得到一个奇怪的值,我不会感到惊讶。该
IFS
变量控制所谓的单词拆分或字段拆分。它基本上定义了 shell 如何在扩展上下文中解析数据(或其他命令,如read
)。Bash 手册解释了这个主题:
以下是一些关于
IFS
命令替换用法的示例:示例 1:
在这两种情况下,
IFS
is<space><tab><newline>
(默认值)、var
ishello world
和 there'sprintf
语句。但请注意,在第一种情况下会执行分词,而在第二种情况下则不会(因为双引号会抑制这种行为)。分词发生在未引用的扩展中。示例 2:
既不
${var}
也不${?}
包含任何空白字符,因此人们可能认为在这种情况下分词不会成为问题。但这不是真的,因为IFS
可能会被滥用。IFS
几乎可以持有任何价值,而且很容易被滥用。示例 3:
这与分词无关,但请注意我们如何使用一些肮脏的技巧来注入代码。
相关问题: