我不明白美元符号是做什么的。尤其是在这种背景下:
for url in $(cat example.txt); do host $url;
答案1
Bash 参考手册 bash手册
3.2.4.3 分组命令
Bash 提供了两种方法将要执行的命令列表分组为一个单元。当命令被分组时,重定向可以应用于整个命令列表。例如,列表中所有命令的输出可以被重定向到单个流。
()
( list )
将命令列表放在括号之间会导致创建子 shell 环境(请参阅命令执行环境),并且列表中的每个命令都会在该子 shell 中执行。由于列表是在子 shell 中执行的,因此在子 shell 完成后变量分配不会保持有效。
这与 不同,
$
因为它随后变成命令替换:
3.5.4 命令替换
命令替换允许命令的输出替换命令本身。当命令被如下括起来时,就会发生命令替换:
$(command)
3.2.4.1 循环结构
for
for命令的语法是:
for name [ [in [words …] ] ; ] do commands; done
展开单词,并对结果列表中的每个成员执行一次命令,名称绑定到当前成员。如果 'in Words' 不存在,则 for 命令会对设置的每个位置参数执行一次命令,就好像已指定 'in "$@"'(请参阅特殊参数)。返回状态是最后执行的命令的退出状态。如果字扩展中没有项,则不执行任何命令,并且返回状态为零。
假设您的 example.txt 包含以下内容:
www.google.com
www.youtube.com
www.facebook.com
您的命令将执行以下操作:
url=www.google.com
host www.google.com
url=www.youtube.com
host www.youtube.com
url=www.facebook.com
host www.facebook.com
host
是返回 URL 的 IP 地址的命令。
答案2
那是命令替换句法。它获取括号内的命令,运行它,然后获取该命令的输出(标准输出)并将其替换为命令字符串的该部分。在这个例子中依赖它的棘手部分是双重的:
- 因为它没有被引用,所以结果将受到文件名扩展的影响(因此,如果 example.txt 的任何部分包含与现有文件名匹配的模式,您将获得这些文件名而不是模式/字符串),并且
- 根据 $IFS 变量将结果拆分为单词。如果 example.txt 包含类似“a filename.txt”的文件名,那么外
for
循环将看到二参数——a
而且filename.txt
很可能做错事。
您经常会看到此示例,因为人们依赖 example.txt 的内容来不包含文件名模式或空格(或制表符)。
此 oneliner 的结果是循环 example.txt 中的假定域名并对它们进行 DNS 查找。
答案3
为了理解bash
代码,设置-x
选项通常非常有帮助:
set -x # within a script / function
或者调用脚本时:
bash -vx ./script.sh
对于循环来说,这有点不太有用。但您始终可以使用命令的第一部分并执行以下操作:
echo for url in $(cat example.txt)
这向您展示了那里发生了什么(至少是结果)。
此功能称为“命令替换”。它将替换$(...)
为命令的输出(不带尾随换行符)。
bash -n ./script.sh
显示语法错误。它会指出你done
的代码末尾缺少的内容。