shell为什么将$(<file)输出的一部分作为命令处理?

代达罗斯

我在阅读有关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$ 
nxnev

$(command)语法command在subshel​​l环境中执行,并将其自身替换为的标准输出command而且,正如Bash Manual所说$(< file)只是速度更快$(cat file)(不过,这不是POSIX功能)。

因此,当您运行时$(<array),Bash执行该替换,然后它将第一个字段用作命令的名称,并将其余字段用作命令的参数:

$ $(<array)
1): command not found

我没有任何1)命令/功能,因此它会显示一条错误消息。

但是在您的特定情况下,您可能会收到另一条错误消息,原因可能是您修改了IFS变量:

$ IFS=n; $(<array)
1)      Ottawa  Ca: command not found

编辑1

我的猜测是您IFS被修改了,所以这就是您的shell尝试执行1) Ottawa Ca而不是的原因1)毕竟,您正在阅读IFS相关文章。如果您IFS最终获得一个怪异的价值,我不会感到惊讶

IFS变量控制所谓的单词拆分字段拆分它基本上定义了Shell在扩展上下文中(或其他命令,如read如何解析数据

Bash手册解释了这个主题

3.5.7分词

Shell扫描参数扩展,命令替换和算术扩展的结果,这些结果在双引号中没有出现,以进行词拆分。

外壳程序将的每个字符$IFS视为定界符,并使用这些字符作为字段终止符将其他扩展的结果拆分为单词。如果IFS没有设置,或者它的值是完全<space><tab><newline>,默认值,然后序列<space><tab>以及<newline>在开始和以前扩张的结果最终会被忽略,而任何序列IFS在开始时没有字符或结束用于分隔单词。如果IFS具有默认值以外的其他值,则在单词的开头和结尾都将忽略空格字符space,,tab和的序列newline,只要空格字符位于IFSIFS空格字符)的值中即可其中的任何字符IFS都不是IFS空格以及任何相邻的IFS空格字符分隔一个字段。IFS空格字符序列也被视为定界符。如果的值为IFSnull,则不会发生词拆分。

显式的空参数(""'')将保留并作为空字符串传递给命令。删除因无值的参数扩展而导致的无引号的隐式空参数。如果将没有值的参数用双引号引起来,则会生成空参数并将其保留并作为空字符串传递给命令。当带引号的空参数作为扩展为非空的单词的一部分出现时,空参数将被删除。也就是说,单词在拆分单词和删除空参数之后-d''成为-d单词。

请注意,如果不发生扩展,则不会执行拆分。

以下是有关IFS和命令替换用法的一些示例

范例1:

$ IFS=$' \t\n'; var='hello     world'; printf '[%s]\n' ${var}
[hello]
[world]

$ IFS=$' \t\n'; var='hello     world'; printf '[%s]\n' "${var}"
[hello     world]

在这两种情况下,IFSis <space><tab><newline>(默认值),varishello world和都有一条printf语句。但是请注意,在第一种情况下执行单词拆分,而在第二种情况下则不执行(因为双引号禁止该行为)。单词拆分发生在不带引号的扩展中。

范例2:

$ IFS='x'; var='fooxbar'; printf '[%s]\n' ${var}
[foo]
[bar]

$ IFS='2'; (exit 123); printf '[%s]\n' ${?}
[1]
[3]

既不包含空格${var}也不${?}包含任何空格,因此人们可能会认为在这种情况下分词不会成为问题。但这不是事实,因为它IFS可能会被滥用。IFS几乎可以拥有任何价值,而且很容易滥用。

范例3:

$ $(echo uname)
Linux

$ $(xxd -p -r <<< 64617465202d75)
Sat Apr 28 12:46:49 UTC 2018

$ var='echo foo; echo bar'; eval "$(echo "${var}")"
foo
bar

这与分词无关,但请注意我们如何使用一些肮脏的技巧来注入代码。

相关问题:

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

将QMap的一部分作为QVector

来自分类Dev

将QMap的一部分作为QVector

来自分类Dev

将Canvas的一部分作为位图

来自分类Dev

如何将命令的一部分作为变量bash传递?

来自分类Dev

将命令字符串的一部分作为变量存储在bash中

来自分类Dev

将nginx url的一部分作为“变量”?

来自分类Dev

将数组的一部分作为函数参数传递

来自分类Dev

将nginx url的一部分作为“变量”?

来自分类Dev

将数组的一部分作为函数参数传递

来自分类Dev

Dovecot Sieve - 如何将消息的一部分作为变量检索

来自分类Dev

将输出文本作为命令按钮的一部分

来自分类Dev

为什么将ffmpeg作为x11的一部分删除?

来自分类Dev

将 Flask 中的字符串列表传递给 javascript 将列表的第一部分作为字符串返回

来自分类Dev

如何使用grep将bash命令输出的一部分解析为变量?

来自分类Dev

将命令输出的一部分分配给 bash 中的变量?

来自分类Dev

使用按钮通过电子邮件将Excel表格的一部分作为PDF附件通过电子邮件发送

来自分类Dev

将标题作为CURL的一部分

来自分类Dev

如何在Docker容器中执行命令作为Bash Shell脚本的一部分

来自分类Dev

如何提取curl命令输出的一部分并将其分配给shell变量?

来自分类Dev

使用Shell将标题作为细节的一部分移动

来自分类Dev

仅将输出的一部分存储到shell变量中

来自分类Dev

什么是shell:您运行的命令的一部分?

来自分类Dev

为什么我的输出的一部分在打印时没有显示?

来自分类Dev

如何提取curl命令输出的一部分并将其分配给shell变量-第2部分?

来自分类Dev

使用GLTF的一部分作为InstancedMesh

来自分类Dev

使用GLTF的一部分作为InstancedMesh

来自分类Dev

使用GLTF的一部分作为InstancedMesh

来自分类Dev

代码的一部分作为模板参数

来自分类Dev

为什么将这个geom_density的一部分遗漏在图中?

Related 相关文章

  1. 1

    将QMap的一部分作为QVector

  2. 2

    将QMap的一部分作为QVector

  3. 3

    将Canvas的一部分作为位图

  4. 4

    如何将命令的一部分作为变量bash传递?

  5. 5

    将命令字符串的一部分作为变量存储在bash中

  6. 6

    将nginx url的一部分作为“变量”?

  7. 7

    将数组的一部分作为函数参数传递

  8. 8

    将nginx url的一部分作为“变量”?

  9. 9

    将数组的一部分作为函数参数传递

  10. 10

    Dovecot Sieve - 如何将消息的一部分作为变量检索

  11. 11

    将输出文本作为命令按钮的一部分

  12. 12

    为什么将ffmpeg作为x11的一部分删除?

  13. 13

    将 Flask 中的字符串列表传递给 javascript 将列表的第一部分作为字符串返回

  14. 14

    如何使用grep将bash命令输出的一部分解析为变量?

  15. 15

    将命令输出的一部分分配给 bash 中的变量?

  16. 16

    使用按钮通过电子邮件将Excel表格的一部分作为PDF附件通过电子邮件发送

  17. 17

    将标题作为CURL的一部分

  18. 18

    如何在Docker容器中执行命令作为Bash Shell脚本的一部分

  19. 19

    如何提取curl命令输出的一部分并将其分配给shell变量?

  20. 20

    使用Shell将标题作为细节的一部分移动

  21. 21

    仅将输出的一部分存储到shell变量中

  22. 22

    什么是shell:您运行的命令的一部分?

  23. 23

    为什么我的输出的一部分在打印时没有显示?

  24. 24

    如何提取curl命令输出的一部分并将其分配给shell变量-第2部分?

  25. 25

    使用GLTF的一部分作为InstancedMesh

  26. 26

    使用GLTF的一部分作为InstancedMesh

  27. 27

    使用GLTF的一部分作为InstancedMesh

  28. 28

    代码的一部分作为模板参数

  29. 29

    为什么将这个geom_density的一部分遗漏在图中?

热门标签

归档