【问题标题】:Unexpected characters coming in bash in while loop在while循环中进入bash的意外字符
【发布时间】:2021-05-03 21:59:58
【问题描述】:

我正在尝试获取 1000 个域的 IP... 下面是我的程序...

#!/bin/bash
yesterday=$(date --date "1 days ago" +%F)

while read -r line comment
do
  
    ip=$(host -4 $line | head -1 | awk -F" " '{print $5}')
  
    echo "$ip"

done <  /home/domainsa/public_html/data/domains/$yesterday-domains.txt

它告诉我

sh -x 域-ip.sh

++ date --date '1 days ago' +%F
+ yesterday=2021-05-02
+ read -r line comment
++ host -4 $'0-96.com\r'
++ head -1
++ awk '-F ' '{print $5}'
+ ip='3(NXDOMAIN)'
+ echo '3(NXDOMAIN)'
3(NXDOMAIN)
+ read -r line comment
++ host -4 $'0-roll.com\r'
++ head -1
++ awk '-F ' '{print $5}'
+ ip='3(NXDOMAIN)'
+ echo '3(NXDOMAIN)'
3(NXDOMAIN)
+ read -r line comment
++ host -4 $'000850.xyz\r'
++ head -1
++ awk '-F ' '{print $5}'
+ ip='3(NXDOMAIN)'
+ echo '3(NXDOMAIN)'
3(NXDOMAIN)
+ read -r line comment
++ host -4 $'00097971.com\r'
++ head -1
++ awk '-F ' '{print $5}'
+ ip='3(NXDOMAIN)'
+ echo '3(NXDOMAIN)'
3(NXDOMAIN)

$ 和 ' 和 \r 不是我所期待的......

知道我哪里做错了吗?

我检查While Loop in Bash Unexpected Character 但我也在使用选定的答案...

PS:有没有更好更快捷的 bash 命令行来获取域的 IP 地址...这是我所知道的,所以写了这个程序。

[编辑]

我正在使用awk -F" " '{print $4}

【问题讨论】:

  • 如果您不想在输入中包含回车符,请通过dos2unix 进行管道传输。

标签: linux bash awk


【解决方案1】:

您的文件 ...domains.txt 包含回车符 (\r)。这些不可打印的字符由 bash 使用 C 样式的字符串 ($'someString') 显示,因此不可打印的回车是可见的。

您可能有 windows 行尾 (\r\n) 而不是 linux 行尾 (\n)。您可以使用dos2unix 转换文件。但可以肯定的是,您可以使用tr -d \\r &lt; ...dommains.txt 删除文件中的所有\r

#!/bin/bash
yesterday=$(date --date "1 days ago" +%F)
tr -d \\r < "/home/domainsa/public_html/data/$yesterday-domains.txt" |
while read -r line comment
do
    host -4 "$line" | head -n1 | awk -F' ' '{print $5}'
done

【讨论】:

  • 如果您在循环内回显,那么该输出也会被awk 过滤。我再次将awk 移动到循环内。请再试一次。如果这仍然不起作用,请编辑您的答案,以便我可以看到您想要回显的确切位置。
  • 除非您需要双引号或取消引号,否则始终在 shell 中使用单引号字符串。见mywiki.wooledge.org/Quotes。不遵循该规则是导致您需要在 tr 参数中进行双重转义的原因。它应该是tr -d '\r',而不是tr -d \\r。话虽如此,这将删除所有\rs,而不仅仅是每行末尾的那些(与dos2unixsed 's/\r$//' 不同,例如),这可能是不可取的(但考虑到OPs 样本可能没问题输入)。
  • @EdMorton 我知道 bash 的不同引用机制。你能解释一下'\r' 应该比\\r 做得更好,除非你坚持尽可能使用单引号的信条吗?对我来说,\\r 看起来比 '\r' 更具可读性,而且更短且更易于输入。另外,正如我在回答中已经写的那样,我使用 tr 专门从 OP 写的内容中删除 all \r (不仅是行尾的那些),文件可能在每行中间包含\rs 以​​将url 与评论分开。
  • 这就像问x=7; echo $x 会比x=7; echo "$x" 做得更好,或者echo '7' | read line 会比echo '7' | read -r line 做得更好。并不是说删除引号和添加反斜杠不会产生相同的结果,而是引用是每个人都应该默认做的事情,而删除引号是你必须做的事情,而不是相反,并且所以这应该是我们在答案中显示的内容,以便阅读它们的新手学习正确的“信条”,并且在其他情况下不会感到惊讶(例如,当他们不引用字符串时)。
  • 不,$x"$x" 之间的区别是巨大的,而 \\r'\r' 是等价的。因为我知道 bash 是如何工作的,所以我经常写 echo word 而不是 echo 'word'\\r 而不是 '\r'。对我来说,“总是使用引号” 感觉就像 “总是使用常量而不是“神奇的”数字”,这可能会导致一些不必要的东西,比如 one=1; i=i+one“总是” 是问题所在。在你的第一条评论中,当一切都很好时,你似乎因为我做了“错误”的事情而叫我出来。但也许我误解了你,你只是想给新手一个一般的报价课。
猜你喜欢
  • 2016-06-04
  • 2015-08-06
  • 2014-05-17
  • 2012-10-04
  • 2015-05-04
  • 1970-01-01
  • 1970-01-01
  • 2020-02-09
  • 1970-01-01
相关资源
最近更新 更多