Debian脚本中使用了&>/dev/null,$?总是返回0

文章目录
  1. 1. 一、问题现象
  2. 2. 二、问题排查
  3. 3. 三、结论

一、问题现象

CentOS中编写了一段Shell脚本,作用很简单,就是监控nginx的配置文件是否发生了变化,如果发生了变化就自动reload一次,脚本如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#!/bin/bash
while true
do
md5=`md5sum /etc/nginx/conf.d/port-to-domain.conf | awk '{print $1}'`
grep ${md5} /tmp/md5result &>/dev/null
if [ $? -ne 0 ];then
echo `date` 'Config File Change'
echo `date` 'Command nginx -t exec'
nginx -t
if [ $? -eq 0 ];then
echo `date` 'Command nginx -t exec success'
nginx -s reload
echo `date` 'Command nginx -s reload exec'
else
echo `date` 'Command nginx -t exec failed'
fi

echo ${md5} > /tmp/md5result
echo `date` 'Change md5result'
else
echo `date` 'Config File NoChange'
fi
sleep 5
done

CentOS中运行一切正常,但是在Debian中运行异常,具体是grep ${md5} /tmp/md5result &>/dev/null的返回值总是0

  • Centos执行过程

1
2
3
4
5
6
7
8
9
[root@txy201-51 ~]# sh -x monitor.sh 
+ true
++ md5sum /etc/nginx/conf.d/port-to-domain.conf
++ awk '{print $1}'
+ md5=37e9863c68386613dd0ee4b3a5183380
+ grep 37e9863c68386613dd0ee4b3a5183380 /tmp/md5result
+ '[' 1 -ne 0 ']' # 正常返回非0值
+ echo 'Config File Change'
Config File Change
  • Debian系统执行过程

1
2
3
4
5
6
7
8
9
10
root@cd3b9bf29db3:/# sh -x monitor.sh 
+ true
+ md5sum /etc/nginx/conf.d/port-to-domain.conf
+ awk {print $1}
+ md5=bca7fa98ab245fa12a4a70a9b15e8b9a
+
+ [ 0 -ne 0 ] # 结果返回0,即使/tmp/md5result不存在也返回0
+ grep bca7fa98ab245fa12a4a70a9b15e8b9a /tmp/md5result
+ date
+ echo Mon Sep 30 09:21:43 UTC 2024 Config File NoChange

二、问题排查

  • 我在Debian的命令行手动执行以上命令,均无问题。

1
2
3
4
5
root@cd3b9bf29db3:/# md5=`md5sum /etc/nginx/conf.d/port-to-domain.conf | awk '{print $1}'`
root@cd3b9bf29db3:/# grep ${md5} /tmp/md5result &>/dev/null
root@cd3b9bf29db3:/# echo $?
2 # 返回正常
root@cd3b9bf29db3:/#
  • 尝试将&>/dev/null删除掉,再测试,发现正常了,不知道是啥原因导致的异常。

1
2
3
4
5
6
7
8
root@cd3b9bf29db3:/# sh -x monitor.sh 
+ true
+ md5sum /etc/nginx/conf.d/port-to-domain.conf
+ awk {print $1}
+ md5=bca7fa98ab245fa12a4a70a9b15e8b9a
+ grep bca7fa98ab245fa12a4a70a9b15e8b9a /tmp/md5result
grep: /tmp/md5result: No such file or directory
+ [ 2 -ne 0 ] # 返回值正常了
  • 我尝试修改了运行脚本的方式,从sh scritp.sh 修改为bash script.sh,结果成功了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
root@cd3b9bf29db3:/# echo > /tmp/md5result 
# bash 与预期相符
root@cd3b9bf29db3:/# bash monitor.sh
Mon Sep 30 09:48:11 UTC 2024 Config File Change
Mon Sep 30 09:48:11 UTC 2024 Command nginx -t exec
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
Mon Sep 30 09:48:11 UTC 2024 Command nginx -t exec success
2024/09/30 09:48:11 [notice] 592#592: signal process started
Mon Sep 30 09:48:11 UTC 2024 Command nginx -s reload exec
Mon Sep 30 09:48:11 UTC 2024 Change md5result
Mon Sep 30 09:48:16 UTC 2024 Config File NoChange
^C
root@cd3b9bf29db3:/# echo 1 > /tmp/md5result
# sh 与预期不相符
root@cd3b9bf29db3:/# sh monitor.sh
Mon Sep 30 09:48:38 UTC 2024 Config File NoChange
Mon Sep 30 09:48:43 UTC 2024 Config File NoChange

三、结论

这个结论是问AI的您遇到的问题很可能是由于sh和bash在处理某些命令或脚本构造时的行为差异所致。在Linux系统中,sh通常指的是POSIX shell,而bash是Bourne Again SHell的简称,它是GNU项目的一个兼容sh的shell程序,提供了许多sh没有的特性和改进。

为啥CentOS可以,Debian不行?
应该是sh的版本等不同造成的。