![在 shell 脚本中处理字符串操作(并测试 grep 的结果)](https://linux22.com/image/156344/%E5%9C%A8%20shell%20%E8%84%9A%E6%9C%AC%E4%B8%AD%E5%A4%84%E7%90%86%E5%AD%97%E7%AC%A6%E4%B8%B2%E6%93%8D%E4%BD%9C%EF%BC%88%E5%B9%B6%E6%B5%8B%E8%AF%95%20grep%20%E7%9A%84%E7%BB%93%E6%9E%9C%EF%BC%89.png)
我已经编写了这个脚本来切换我的触摸板(我将对其进行按键绑定),但它不起作用。为什么这段代码不起作用?那么如何才能更优雅的完成这个功能呢?
#!/bin/sh
if [ "synclient | grep TouchpadOff | grep -o -E '[0-9]+'" ]
then
synclient TouchpadOff=0
notify-send "Touchpad Enabled"
else
synclient TouchpadOff=1
notify-send "Touchpad Disabled"
fi
答案1
当你写作时
if [ "some string or other" ]
then
运算[
符不会运行some string or other
,它只是看到一个非空字符串并说这是一个true
值。
你要
if [ "`synclient | grep TouchpadOff | grep -o -E '[0-9]+'`" ]
或者更现代的
if [ "$(synclient | grep TouchpadOff | grep -o -E '[0-9]+')" ]
但实际上没有必要查看命令是否生成字符串,因为 grep 会生成退出代码,因此
if synclient | grep TouchpadOff | grep -q -E '[0-9]+'
then
应该做你想做的事。我不知道 synclient 的输出格式,但我希望您可以毫不费力地将两个 grep 合并为一个。
答案2
伊卡洛斯给了一个很好的答案。你的问题很难回答,因为你没有准确解释脚本应该做什么,所以我们被迫对其进行逆向工程(并猜测你在想什么)。
icarus 猜测您正在查看输出是否synclient
包含包含“TouchpadOff”和数字的行。
我猜您假设/期望 的输出synclient
包含一行包含“TouchpadOff”和一个数字,并且您希望查看该数字是否为 0。
如果伊卡洛斯猜对了,请停止阅读。
如果我猜对了,我们可以调整倒数第二个(倒数第二个)命令 伊卡洛斯的回答如下:
if [ "$(synclient | grep TouchpadOff | grep -o -E '[0-9]+')"!= 0]
(测试数字是否为零)并且这应该是相当可移植的。但可能还有一些更短的方法:
如果你使用 bash,你可以这样做
如果((“$(synclient | grep TouchpadOff | grep -o -E '[0-9]+')”))
使用语法。这样做的问题包括:
(( expression ))
- 它不符合 POSIX 标准,因此必须根据具体情况来考虑除 bash 之外的 shell 中的行为。
- 如果命令的输出为空,则将其视为 0。
如果您对输出的了解
synclient
比您所显示的更多,您可以编写更智能的grep
.例如,如果您相当确定 的输出synclient
将包含一行,其中包含看起来像 的字符串,其中TouchpadOff = number
number
是一个没有前导零的非负整数(即,它可能是0
,1
, or42
,但不是01
,0.5
, oroff
),并且 之前和/或之后可能有也可能没有空格,=
那么你可以这样做如果!同步客户端 | grep -q '触摸板关闭[[:空格:]]*=[[:空格:]]*0'
在某些版本
grep
(例如 GNUgrep
)中,您可以将其缩短为如果!同步客户端 | grep -q '触摸板关闭\s*=\s*0'
我添加了
!
来反转命令的真值。grep -q 'TouchpadOff…=…0'
如果找到的话(显然)会成功TouchpadOff = 0
——但是,如果我的猜测是正确的,你想要做synclient TouchpadOff=0
命令如果当前值为不是零。