我正在努力处理一个非常简单的 Cygwin 脚本,但我无法理解它。希望有人能帮我一把。
这是脚本:
h=www.ibm.com
for ip in $(dig $h +short); do echo "XX ${ip} XX"; done
预期输出(使用 Debian Buster Linux 和 bash 5.0.3(1)-release 进行测试:
XX www.ibm.com.cs186.net. XX
XX outer-global-dual.ibmcom-tls12.edgekey.net. XX
XX e7817.dscx.akamaiedge.net. XX
XX 37.26.112.89 XX
在 Cygwin 中使用 bash 4.4.12(3)-release 运行相同的脚本,输出完全不同:
XXwww.ibm.com.cs186.net.
XXouter-global-dual.ibmcom-tls12.edgekey.net.
XXe7817.dscx.akamaiedge.net.
XX37.26.112.89
我不敢相信发生了什么。这一定是显而易见的事情,但我看不到。为什么 Cygwin 的 bash 会修剪最后一个“XX”和前导空格?
问候,
答案1
该dig
实用程序似乎在 Cygwin 上输出以回车符结尾的行(我无法对此进行测试)。当输出该字符时,它将光标移回到行的开头,这会导致格式奇怪的输出。
要解决此问题,请从 的输出中去除尾随回车符dig
:
query=www.ibm.com
dig "$query" +short | sed 's/[[:space:]]*$//' |
while IFS= read -r response; do
printf 'XX %s XX\n' "$response"
done
这用于 从 的输出中sed
删除任何匹配的内容。该模式匹配行末尾的零个或多个类似空格的字符,其中回车符是一个。[[:space:]]*$
dig
我选择使用while
循环而不是你的for
循环。从概念上讲,while
循环用于在数据到达时从不确定长度的数据流中读取行。 Afor
另一方面,循环总是静止的字符串集。这意味着for
在 shell 读取所有输出dig
并将其分割成单词(并对每个单词应用文件名通配)之前,循环无法启动。一般来说,for
由于潜在的引用问题,使用从程序读取输出行是有问题的,而且也不优雅并且可能占用大量内存(因为所有输出都必须由 shell 存储)。