执行命令的if语句实际值是什么?管道命令if语句逻辑疑问
嘿,先给你掰明白最核心的点:shell里的if判断的不是输出内容,而是命令执行后的退出状态码——退出码为0(表示命令执行成功/符合预期)时,if会走then分支;非0(执行失败/没达到预期)时走else分支。
接下来咱们一点点拆解你给出的这条命令链:if linux-command-1 | linux-command-2 | linux-command-3 > /dev/null
1. 管道链的执行顺序
这一串管道是按从左到右的顺序跑的:
- 先启动
linux-command-1,它输出的内容会通过管道(|)直接传给linux-command-2当输入 linux-command-2处理完输入后,再把自己的输出传给linux-command-3当输入- 最后
linux-command-3处理完输入,它的输出会被重定向到/dev/null——这玩意儿就是个“黑洞”,扔进去的东西直接消失,不会显示在你的终端上
2. if到底在判断啥?
默认情况下(拿最常用的bash来说),整个管道链的退出状态码等于最后一个命令(也就是linux-command-3)的退出码:
- 如果
linux-command-3顺利跑完(退出码0),if就觉得条件为真,执行后面的then代码块 - 如果
linux-command-3跑崩了或者没达到预期(退出码非0),if就认为条件为假,执行else代码块
小补充:要是你手动开了
pipefail选项(比如先执行set -o pipefail),那整个管道链的退出码就会变成第一个跑失败的命令的退出码——只要管道里某一步的命令炸了,整个链的退出码就非0,if条件直接为假。
3. 加> /dev/null的意义是什么?
这个重定向纯粹是为了避免linux-command-3的输出乱飘到终端上,完全不影响if的判断逻辑——哪怕你把输出重定向到某个文件,只要linux-command-3的退出码没变,if的判断结果就一模一样。
给你举个实际能用的例子:
比如我想检查系统日志里有没有严重错误信息,就可以这么写:
if cat /var/log/syslog | grep "critical error" | head -1 > /dev/null then echo "糟了!日志里出现严重错误了!" else echo "还好,没找到严重错误~" fi
这里head -1只要能拿到grep搜出来的内容(退出码0),if就会触发then分支;要是grep啥也没搜到,head -1没东西可输出,退出码就非0,触发else分支。而> /dev/null就是不让head -1的输出(也就是搜到的那一行错误日志)显示在终端上,避免干扰。
内容的提问来源于stack exchange,提问作者HackXIt

