变量不解析为字符串

Ion*_*Sme 10 text command-line bash scripts

问题

我尝试在 bash 脚本中以下列方式提取 wifi 的信号电平(引号似乎没有区别):

string="$(iwconfig wlan0 | grep -I Signal)"
Run Code Online (Sandbox Code Playgroud)

如果 I echo $string,我得到了我的期望:

Link Quality=63/70 Signal level=-47dBm
Run Code Online (Sandbox Code Playgroud)

但是,如果我尝试获取子字符串, echo ${string:5},它会返回相同的内容。


调试:

如果我将 的输出wconfig wlan0 | grep -I Signal直接粘贴到变量中:string="Link Quality=63/70 Signal level=-47dBm"那么一切都按预期进行。

string="$(iwconfig wlan0 | grep -I Signal)"
Run Code Online (Sandbox Code Playgroud)

问:根据网上的说法,所有的bash变量都是以字符串的形式存储的。因此,调试结果应该与我原来的问题相同。是否有某种原因在原始问题中没有将其解析为文本?

ste*_*ver 15

这是因为echo $string不是简单地打印string; 它首先执行split+glob操作 - 其后果之一是省略了前导空格:

$ string=$(iwconfig wls1 | grep Signal)
$ echo $string
Link Quality=38/70 Signal level=-72 dBm
Run Code Online (Sandbox Code Playgroud)

然而

$ echo "$string"
          Link Quality=38/70  Signal level=-72 dBm  
Run Code Online (Sandbox Code Playgroud)

我们可以看到在开头有一个空格字符序列$string- 实际上有超过 5 个,所以删除 5 仍然留下一个带有前导空格的字符串,未加引号的子字符串扩展 ( ${string:5}) 也省略了:

$ echo "${string:5}"
     Link Quality=38/70  Signal level=-72 dBm  
$ echo ${string:5}
Link Quality=38/70 Signal level=-72 dBm
Run Code Online (Sandbox Code Playgroud)

有关其他讨论,请参阅:

  • Tl;dr 总是引用你的变量 (4认同)

Win*_*nix 6

这适用于我的机器:

$ string="$(iwconfig wlp60s0 | grep -I Signal)"
$ echo $string
Link Quality=68/70 Signal level=-42 dBm
$ echo $string | cut -d' ' -f4,5
level=-42 dBm
Run Code Online (Sandbox Code Playgroud)
  • 对于您的机器,请替换wlp60s0wlan0.
  • 请注意,这是使用 Ubuntu 16.04 和 Ubuntu 19.04,其中42和之间有空格dBm。因此,cut命令命令打印字段#4 和#5。在您的问题中没有空格,所以我不确定您使用的是什么版本。

您还可以使用:

$ echo $string | cut -d'=' -f3
-42 dBm
Run Code Online (Sandbox Code Playgroud)
  • 在这种情况下,cut被告知=用作字段分隔符。

如果您想使用${string...}正确的语法是:

$ echo ${string##*=}
-38 dBm

$ echo "${string##*=}"
-38 dBm  
Run Code Online (Sandbox Code Playgroud)

任何一种方法都可以在最后一个=. 5在你的问题中的原始方法我不明白它是如何工作的。