问题
脚本ls 执行没有找到目标文件,在脚本中已经判断了状态码,执行失败应该退出脚本。
错误:ls: cannot access /home/oracle/ETL/tmp_crl_cl/*mid_order_item_mon*: No such file or directory
shell 脚本:
file=`ls /home/oracle/ETL/tmp_crl_cl/*$1*| head -n1`
if [ $? != 1 ];then
echo 未知错误 >> /home/oracle/ETL/1.txt
exit 1
fi
awk 'NR==3{print $3}' $file >> /home/oracle/ETL/1.txt
解决步骤
1.pstree查看 shell脚本进程
参数
-p Show PIDs. PIDs are shown as decimal numbers in parentheses after each process name. -p implicitly disables compaction.
-a Show command line arguments. If the command line of a process is swapped out, that process is shown in parentheses. -a implicitly disables
compaction.
命令:
pstree -pa 46208
显示结果:
sh,46208 tmp_20190401.sh mid_order_item_mon
└─awk,46212 NR==3{print\040$3}
脚本没有退出,在执行awk命令。ls执行错误,导致$file目前为空值,所以一直脚本在awk命令行卡死(定义变量为命令执行结果,命令执行失败,该值未空值)
2.echo $?
在脚本中echo $?,发现不管ls执行情况,$?都为0。
发现问题:file=`ls /home/oracle/ETL/tmp_crl_cl/*$1*| head -n1`
使用管道命令,每条命令都是独立的,head -n1为上一次执行的命令,所以不管ls执行成功与否,$?都为0。
2.1修改后脚本
file=`ls /home/oracle/ETL/tmp_crl_cl/*$1*`
if [ $? != 0 ];then
echo 未知错误 >> /home/oracle/ETL/1.txt
echo 文件未找,脚本退出
exit 1
fi
file=`ls /home/oracle/ETL/tmp_crl_cl/*$1*| head -n1`
awk 'NR==3{print $3}' $file >> /home/oracle/ETL/1.txt
总结
使用管道命令后面连接起来写在一行的命令,不是一条命令,是分步执行的。
附:命令状态码
0 | 命令成功结束 |
1 | 通用未知错误 |
2 | 误用Shell命令 |
126 | 命令不可执行 |
127 | 没找到命令 |
128 | 无效退出参数 |
128+x | Linux信号x的严重错误 |
130 | 命令通过Ctrl+C控制码越界 |
255 | 退出码越界 |
shell内置参数
$0 | 当前脚本的文件名 |
$n | 传递给脚本或函数的参数。n 是一个数字,表示第几个参数。例如,第一个参数是$1,第二个参数是$2。 |
$# | 传递给脚本或函数的参数个数。 |
$* | 传递给脚本或函数的所有参数。 |
$@ | 传递给脚本或函数的所有参数。被双引号(" ")包含时,与 $* 稍有不同,下面将会讲到。 |
$? | 上个命令的退出状态,或函数的返回值。 |
$$ | 当前Shell进程ID。对于 Shell 脚本,就是这些脚本所在的进程ID。 |