Linux Bash if语句,带有来自文件的grep-eq 0 from$?

Linux Bash if语句,带有来自文件的grep-eq 0 from$?,linux,bash,shell,Linux,Bash,Shell,我正在尝试让这个小脚本工作,告诉我是否启用了两个选项之一。它似乎对第一个if语句有效,但对下两个语句无效。有人能给我指出正确的方向让这项工作顺利进行吗 编辑:这个脚本的目的是我可以运行,检查tun0(或者ifconfig输出中存在的tun的任何变体)是否存在,如果存在,我就完成了,如果没有,我需要检查其他两行中是否有一行在“test.ini”文件中标记为yes,以查看tun0缺失是否有任何问题,或者我可以跳过它。第7行和第12行是该地区让我陷入困境的地方。很抱歉,我之前没有澄清这一点 1 #!

我正在尝试让这个小脚本工作,告诉我是否启用了两个选项之一。它似乎对第一个if语句有效,但对下两个语句无效。有人能给我指出正确的方向让这项工作顺利进行吗

编辑:这个脚本的目的是我可以运行,检查tun0(或者ifconfig输出中存在的tun的任何变体)是否存在,如果存在,我就完成了,如果没有,我需要检查其他两行中是否有一行在“test.ini”文件中标记为yes,以查看tun0缺失是否有任何问题,或者我可以跳过它。第7行和第12行是该地区让我陷入困境的地方。很抱歉,我之前没有澄清这一点

 1 #!/bin/bash
 2
 3 if [[ $(ifconfig|grep -iq tun;echo $?) -eq 0 ]]
 4 then
 5         echo "This unit has tun0"
 6 else
 7         if [[ $(grep -iq enabled=yes test.ini|grep -v "Auto\|Purge\|AD"|awk '{print $1}';echo $?) -eq 1 ]]
 8         then
 9                 echo "This unit has file copy enabled"
 10                 echo "but does not have tun0"
 11         else
 12                 if [[ $(grep -iq AutoSyncEnabled=yes test.ini|grep -v Exchange|awk '{print $1}';echo $?) -eq 1 ]]
 13                 then
 14                         echo "This unit has rsync enabled"
 15                         echo "but does not have tun0"
 16                 else
 17                         echo "No tun0 but no requirement either."
 18                 fi
 19         fi
 20 fi

当没有匹配项时,您希望Awk将其退出代码设置为1,但默认情况下Awk不会这样做。你需要像这样做

awk '{ success ... exit 0 } END { exit 1 }'
显式设置退出代码

if[[$(something;echo$?)-eq 0]
也是反模式的巨大泥潭。你只是想要

if something
--检查
$?
如果
做的事情;这正是它的目的

根据您在下面的评论,您的意思显然是如果grep-i something test.ini | something没有
-q
(这会抑制来自
grep
的任何输出),它可以重构为

if awk '/something/ && ... something else' test.ini
除了从
grep
中丢失
-i
标志之外。显而易见的修复方法是将输入行小写(同样,将regex小写,因为否则您当然不会得到匹配!),但还有其他方法可以让Awk在忽略大小写的情况下进行比较

if awk 'tolower($0) ~ /something/ && ... something else' test.ini
带着这些话,试试这个重构版本

#!/bin/bash

if ifconfig | grep -iq tun; then
     echo "This unit has tun0"
elif ! awk 'tolower($0) ~ /enabled=yes/ && !/Auto|Purge|AD/{
        print $1; fail=1} END { exit fail }' test.ini
then
    echo "This unit has file copy enabled"
    echo "but does not have tun0"
elif ! awk 'tolower($0) ~ /autosyncenabled=yes/ && !/Exchange/{
        print $1; fail=1} END { exit fail }' test.ini
then
    echo "This unit has rsync enabled"
    echo "but does not have tun0"
else
    echo "No tun0 but no requirement either."
fi
您的Awk脚本将输出打印为标准输出;如果不需要这样做,取出
打印
,在第一次成功时只
退出0
,否则
结束{exit 1}'
,如下所示

:
elif awk 'tolower($0) ~ /enabled=yes/ && !/Auto|Purge|AD/{ exit 0 }
        END { exit 1 }' test.ini
then
:

还要注意
elif
,以避免
if
流嵌套太深。

我最终找到了两种方法来实现这一点。我采用的方法是,使用我们的一个内部程序读取该文件,该文件只给出yes/no的输出

== [Yy]es ]]
我还发现我可以继续沿着我要去的兔子洞往下走,使用太多的管道,以获得我想要的输出

if [[ $(grep -i enabled=yes test.ini|grep -v "Auto\|Purge\|AD"|awk '{print $1}'|cut -b 9-11) == [Yy]es ]]
然而,使用定期读取该文件的内部程序,并让它输出yes或no,似乎要简单得多(并且没有管道/长语句等)

正如延斯指出的,我最大的问题是管道太多。此外,正如123所指出的,我没有意识到美元?只是在最后一个管道上完成的,而不是整个命令


谢谢大家在这方面的帮助。来自每个人评论的大量信息将对未来的脚本以及如何编写脚本的选择有很大帮助。

在第7行,
grep-iq…
将返回一个“安静”的输出。不确定这是否需要
if[$(ifconfig | grep-iq tun;echo$?)-eq 0]
应该类似于
if-ifconfig | grep-iq tun
grep | grep | awk
是一种反模式!一个管道肯定没用,可能两个都没用。
tun_devices=(/sys/class/net/tun*);如果[-e$tun_设备]];然后echo“至少存在一个tun设备;具体来说,其中有${tun#u设备[@]}。”;fi
…或者,当然,
[-e/sys/class/net/tun0]
,如果您只关心其中一个的话。非常喜欢使用elif来避免嵌套。不过,该脚本在很大程度上将整个文件转储到了我的屏幕上。其中的第一个grep是对任何启用了的行进行grepping,但是由于它将返回多个值,所以第二个grep使用-v输出,以便删除额外的值。grep-i enabled返回几行AutoBackupEnabled=No;启用/禁用Datasweep PurgeEnabled=否;从源目录中删除旧文件AutoSyncEnabled=yes;启用/禁用安全数据同步。grep-v删除了我不想要的额外结果。如果不访问您想要对其做出反应的精确的
ifconfig
输出和
test.ini
的内容,就无法进一步解决此问题。而且你的评论不太可读;也许你应该把你的问题包括在这些细节中。基于你实际上并不打算使用
grep-q
grep | awk
awk | cut
的理解,更新了一些细节