问题
我尝试在 bash 脚本中以以下方式提取 wifi 的信号级别(引号似乎没有区别):
string="$(iwconfig wlan0 | grep -I Signal)"
如果我echo $string
,我会得到我期望的结果:
Link Quality=63/70 Signal level=-47dBm
但是如果我尝试获取一个子字符串,echo ${string:5}
它会返回相同的内容。
调试:
如果我将输出wconfig wlan0 | grep -I Signal
直接粘贴到变量中:string="Link Quality=63/70 Signal level=-47dBm"
那么一切都按预期工作。
echo $string
# Link Quality=63/70 Signal level=-47dBm
echo ${string:5}
# Quality=63/70 Signal level=-47dBm
问题:根据互联网,所有 bash 变量都存储为字符串。因此,调试结果应该与我原来的问题相同。原始问题中没有将其解析为文本的原因是什么?
答案1
这是因为echo $string
不会简单地打印值string
;它首先执行分裂+统一操作——其后果之一是前导空格被省略:
$ string=$(iwconfig wls1 | grep Signal)
$ echo $string
Link Quality=38/70 Signal level=-72 dBm
然而
$ echo "$string"
Link Quality=38/70 Signal level=-72 dBm
我们可以看到,在 的开头有一个空格序列$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
更多讨论请参见:
答案2
这在我的计算机上有效:
$ 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
- 对于您的机器,请将其替换
wlp60s0
为wlan0
。 - 笔记
42
这是使用 Ubuntu 16.04 和 Ubuntu 19.04,其中和之间有一个空格dBm
。因此,cut
命令被指示打印字段 #4 和 #5。在您的问题中没有空格,所以我不确定您使用的是哪个版本。
您还可以使用:
$ echo $string | cut -d'=' -f3
-42 dBm
- 在这种情况下,
cut
被告知用作=
字段分隔符。
如果您想使用${string...}
,正确的语法是:
$ echo ${string##*=}
-38 dBm
$ echo "${string##*=}"
-38 dBm
这两种方法都可以用于获取最后一个 之后的子字符串=
。我不明白你问题中的原始方法5
是如何工作的。