shell exit 1退不出问题

在执行到某个条件的时候,需要让他异常退出,终止脚本运行,可是发现exit 1 并不能成功。

原因:因为只是退出了子进程。

何时进入子进程:我当时是管道,即 | 符号。也有别的情形。

排查方法:打印当前进程号 echo $bashpid

解决方法:在子进程结束的地方,再捕捉返回值,然后退出。

就比如我是进入管道后,开始进入子进程的,然后while循环去取每一行判断。那么就在while循环结束的地方,加一次捕捉

1)测试数据 data.txt

cat ./data.txt
1
2
3

2)测试脚本test.sh。测试方法:当读到行的内容为2的时候让程序退出

从cat  ./data.txt | while read line到 done这行是子进程

echo  "================最开始============"
echo  "$BASHPID"
echo  "===================================="

echo "${line}"
cat  ./data.txt | while read line
do
echo  "================进入管道后============"
echo  "$BASHPID"
echo  "===================================="
   echo "${line}"
   if [ ${line} -eq 2 ] ;then
      exit 1
      echo "未退出"
   fi
   echo "返回值"
   echo "$?"
   echo "返回值"
   if [ $? -eq 1 ] ;then
      echo "导入失败退出1!"
      exit 1
    fi
done
#===这里不要加语句,否则返回值可能会在这里被改变===
  if [ $? -eq 1 ] ;then
     echo "导入失败退出2!"
     exit 1
  fi
echo  "================出循环后============"
echo  "$BASHPID"
echo  "===================================="
echo "$?"
if [ $? -eq 1 ] ;then
   echo "导入失败退出3!"
   exit 1
fi
if [[ $? -eq 1 ]] ;then
   echo "导入失败退出4!"
   exit 1
fi

3)测试结果

可见父进程号是8487,子进程号是8489。

程序在读到行值为2的时候退出了子进程,子进程里的其他程序没有再执行了。捕捉子进程的退出码后走了“导入失败退出2!” 程序结束了。后面的也没有执行。是想要的效果。

(我这里是调度任务需要让他走错误退出报警,所以返回的是1,如果你想不报警正常退出的话,返回值给0)

sh test.sh 
================最开始============
8487
====================================

================进入管道后============
8489
====================================
1
0
================进入管道后============
8489
====================================
2
导入失败退出2!

踩过的坑:
一开始以为是循环的问题,专门写了个双重循环,测试了下发现不是。

以为是if的问题,发现也不是。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
根据提供的引用内容,问题中的shell脚本在读取到行值为2时退出了子进程,并捕捉到了退出码。子进程结束后,后面的程序也没有执行。这是预期的结果。但问题是脚本无法退出。 根据引用中的脚本代码,我们可以看到在退出子进程后,使用了条件判断来判断退出码是否为1,如果是1则继续退出脚本。但在这里我们需要注意的是,每次使用`$?`来获取上一个命令的退出码时,都会被刷新为最新的命令退出码。所以在条件判断中多次使用`$?`可能会导致不准确的结果。 为了解决这个问题,我们可以将子进程的退出码保存到一个变量中,然后在后续的条件判断中使用这个变量来避免`$?`被刷新的问题。 以下是一个修改后的示例脚本: ```shell from cat ./data.txt | while read line do echo "================最开始============" echo "$BASHPID" echo "====================================" echo "${line}" cat ./data.txt | while read line do echo "================进入管道后============" echo "$BASHPID" echo "====================================" echo "${line}" if [ ${line} -eq 2 ]; then exit_code=1 echo "未退出" fi echo "返回值" echo "$exit_code" echo "返回值" if [ $exit_code -eq 1 ]; then echo "导入失败退出1!" exit 1 fi done #===这里不要加语句,否则返回值可能会在这里被改变=== if [ $exit_code -eq 1 ]; then echo "导入失败退出2!" exit 1 fi echo "================出循环后============" echo "$BASHPID" echo "====================================" echo "$?" if [ $exit_code -eq 1 ]; then echo "导入失败退出3!" exit 1 fi if [[ $exit_code -eq 1 ]]; then echo "导入失败退出4!" exit 1 fi done ``` 这样修改后的脚本将子进程退出码保存在变量`exit_code`中,并在后续的条件判断中使用该变量。这样就避免了使用`$?`时的刷新问题,可以正确判断退出码并退出脚本。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [shell exit 1退不出问题](https://blog.csdn.net/gegeyanxin/article/details/124152819)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* [shell编程 创建shell脚本 shell 基础语法 shell流程控制语法 shell函数](https://download.csdn.net/download/weixin_66328465/87212912)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值