【shell】shell遇到错误自动退出set -e|set -u|set -x

set -e      #脚本里面有返回值非0命令/运行失败的命令 就退出

set -u       #如果遇到不存在的变量,就退出

sh -x  my.sh 回整个脚本都输出调试信息,太多了

使用set -x开启某一段的调试信息:

set -x 开始调试;

set +x 结束调试;

-x还有另一种写法-o xtrace。

set -o xtrace

set -e 的陷阱

1,管道命令

set -o pipefail

set -e有一个例外情况,就是不适用于管道命令。
就是多个子命令通过管道运算符(|)组合成为一个大的命令。Bash 会把最后一个子命令的返回值,作为整个命令的返回值。即只要最后一个子命令不失败,管道命令总是会执行成功,因此它后面命令依然会执行,set -e就失效了。

例子:假如foo命令不存在

foo | echo a

foo是一个不存在的命令,但是foo | echo a这个管道命令会执行成功,导致脚本会继续往后执行

#!/bin/bash

set -e

for species in `something`;do
    ...
    for id in `something`;do
       cmd1 | cmd2 | grep sth
    done | cmd3 | cmd4 > somefile
done
cmd5

内层循环某一次grep失败,会导致整个内层循环退出,而由于内层循环与后面的管道形成了一个整体,这个整体的最后一个命令(重定向到somefile文件)不会失败,所以这个整体不会触发ERREXIT。外层循环可以顺利运行,遍历整个列表

摘自:http://t.csdn.cn/gRlFp

2, grep匹配不到会导致退出

#!/usr/bin/env bash
set -e
PID=$(ps -ef | grep "进程标识" | grep -v grep | awk '{print $2}')
echo "pid is: "$PID

如果没有相应的进程会因为第二个 grep :grep "进程标识"匹配不到,退出码 $? 为 1,set -e导至脚本退出,没有执行echo输出

解决办法:使用bash的分组命令功能:Grouping Commands

#!/usr/bin/env bash
set -e
PID=$(ps -ef | { grep "进程标识" || true; } | { grep -v grep || true; } | awk '{print $2}')
echo "pid is: "$PID

参考:linux shell set -e grep 匹配不到导致脚本退出问题https://blog.csdn.net/zswspock/article/details/119245835

下面的也能使得set -e 失效

command | grep -r ${str} | tee a.log

tee a.log 可以改变命令的执行后的返回值,而不改变命令本身的执行结果

你可能感兴趣的:(bash,开发语言)