常规做法

cat >test.sh<<EOF''
#!/bin/bash exit_script(){
exit 1
} echo "before exit"
exit_script
echo "after exit"
EOF chmod a+x test.sh
./test.sh
echo $? # 输出
before exit
1

可以看到直接使用exit可以退出脚本,并且可以将错误码作为参数传递。下面我们将脚本做一点点改动。

存在的问题

cat >test.sh<<EOF''
#!/bin/bash exit_script(){
exit 1
} echo "before exit"
:|exit_script
echo "after exit"
EOF chmod a+x test.sh
./test.sh
echo $? # 输出
before exit
after exit
0

管道(|)中执行exit_script函数,不会退出整个脚本!原因在于,exit只能退出它所在的Shell,而放在管道中执行的命令/函数都是在独立的Shell(Sub-Shell)中执行的,所以上面脚本的进程树是这个样子的:

 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
17510 26959 26959 26959 pts/0 14049 Ss 0 0:00 \_ -bash
26959 13843 13843 26959 pts/0 14049 S 0 0:00 | \_ /bin/bash ./test.sh
13843 13844 13843 26959 pts/0 14049 S 0 0:00 | | \_ :
13843 13845 13843 26959 pts/0 14049 S 0 0:00 | | \_ /bin/bash ./test.sh
13845 13846 13843 26959 pts/0 14049 S 0 0:00 | | \_ exit 1

自上往下,各个PID的含义如下表:

PID 说明
26959 ./test.sh所在的Shell
13843 管道中:新开的Shell
13844 :命令
13845 管道中exit_shell新开的Shell
13846 exit命令

使用trapkill退出整个脚本

cat >test.sh<<EOF''
#!/bin/bash export TOP_PID=$$
trap 'exit 1' TERM exit_script(){
kill -s TERM $TOP_PID
} echo "before exit"
:|exit_script
echo "after exit"
EOF chmod a+x test.sh
./test.sh
echo $? # 输出
before exit
1

这里首先在脚本的主进程中捕获(trap) TERM信号: 当主进程接收到TERM信号后,会执行exit 1;再在Sub-Shell中向脚本主进程发送TERM信号,这样就可以让整个脚本退出了!

Shell中, 退出整个脚本的更多相关文章

  1. shell中引用其他脚本的方法

    在Shell中引用其他脚本的方法是source   filename.sh 或    .    filename.sh 注意:      .   和   filename.sh之间必须有空格

  2. Shell中退出状态码exit

    shell中运行的每个命令都使用退出状态码(exit status)来告诉shell它完成了处理.退出状态码是一个0~255之间的整数值,在命令结束时由命令传回shell. 1 .查看退出状态码 Li ...

  3. linux shell中判断bash脚本输入的参数个数

    看下面的一段程序. #!/bin/bash ]; then echo "参数个数为$#个" else echo "没有参数" fi

  4. linux shell 中的位置变量

    对于linux shell 中的位置变量,我一直以来都是吐不出来又咽不下去,每次看到都不懂,不懂了就去百度google,看完了又忘,真是慢性咽炎啊.现在认真想想也是,其实自己一直以来都没有好好学习过, ...

  5. Linux - 简明Shell编程11 - 调用脚本(CallTheScript)

    脚本地址 https://github.com/anliven/L-Shell/tree/master/Shell-Basics 示例脚本及注释 主脚本: CallTheScript.sh #!/bi ...

  6. Shell - 简明Shell入门11 - 调用脚本(CallTheScript)

    示例脚本及注释 主脚本: CallTheScript.sh #!/bin/bash . ./11-subscript.sh # 调用其他脚本;注意点号"."和文件路径之间有一空格; ...

  7. Shell中脚本变量的作用域

    原文地址:http://blog.csdn.net/abc86319253/article/details/46341839    在shell中定义函数可以使代码模块化,便于复用代码.不过脚本本身的 ...

  8. Linux Shell脚本攻略:shell中各种括号()、(())、[]、[[]]、{}的作用

    技巧小结: 字符串比较用双中括号[[ ]]:算数比较用单中括号[ ]——左右留空格 算数运算用双小括号(( )) :shell命令及输出用小括号( )——左右不留空格 快速替换用花括号{ }——左右留 ...

  9. centos shell脚本编程2 if 判断 case判断 shell脚本中的循环 for while shell中的函数 break continue test 命令 第三十六节课

    centos  shell脚本编程2 if 判断  case判断   shell脚本中的循环  for   while   shell中的函数  break  continue  test 命令   ...

随机推荐

  1. Polymorphic form--多态表单

    一个ruby on rails项目,用户和公司的模型都有地址. 我要创建一个地址表,包含用户和公司表的引用,比直接做下去要好一点,这回让我的数据库设计保持干净. 我的第一印象是,这似乎很难实现,外面所 ...

  2. iOS 微信支付SDK与微信友盟分享两者同时集成时,出现的问题与解决之路。

    这两天改版一个旧的APP,要旧貌换新颜,拿到app后进行编译,一直报下面的错误. 报不认识的符号名PayReq错误.奇怪,啥也没动就这样,真不知道给的包是不是本来就是个报错的工程. 不管怎样,要对它修 ...

  3. springboot jpa 多条件查询(多表)

    前几天写的,贴上来. 实体类. package com.syl.demo.daomain; import lombok.Data; import javax.persistence.*; /** * ...

  4. c#调用webservices

    有两种方式,静态调用(添加web服务的暂且这样定义)和动态调用: 静态调用: 使用添加web服务的方式支持各种参数,由于vs2010会自动转换,会生成一个特定的Reference.cs类文件   动态 ...

  5. rpm包的rpmbuild spec文件详解

    http://machael.blog.51cto.com/829462/213477 上一篇日志写到,为什么要制作rpm包,以及如何使用.src.rpm文件生成rpm包.最后部分还看到.src.rp ...

  6. [转]EntityFramework的多种记录日志方式,记录错误并分析执行时间过长原因(系列4)

    本文转自:https://www.cnblogs.com/GuZhenYin/p/5556732.html Entity Framework 延伸系列目录 今天我们来聊聊EF的日志记录. 一个好的数据 ...

  7. Oracle11g密码过期处理方法

    首先 查询密码有效期:   SELECT * FROM dba_profiles s WHERE s.profile='DEFAULT' AND resource_name='PASSWORD_LIF ...

  8. 面向对象(基础oop)之垃圾回收与静态成员

    大家好,我叫李京阳,,很高兴认识大家,之所以我想开一个自己的博客,就是来把自己所了解的知识点通过自己的话写一下,希望被博客园的朋友们点评和一起讨论一下,也希望从博客园中多认识一些软件开发人员!现在我开 ...

  9. linux下安装jdk8

    https://www.cnblogs.com/shihaiming/p/5809553.html

  10. HDU3085(KB2-G 双向bfs)

    Nightmare Ⅱ Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...