常规做法

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. ARM的体系结构与编程系列博客——ARM的历史与应用范围

    前言 最近我感觉自己比较浮躁,重来没有好好地沉下心来做一件事情,而且针对自己在专业水平上仍然还有很多欠缺,于是我想我应该为自己做些什么来证明一下自己真的是潜心研究东西的人,于是我萌生了一个想法,真正地 ...

  2. Python---战机小游戏,学习pygame

    import pygame # 导入游戏包 pygame.init() # 导入并初始化所有pygame模块,使用其他模块之前必须先调用init()方法 print('下面是游戏代码:') # 绘制矩 ...

  3. 通向全栈之路——(3)node环境搭建

    1:更新系统 sudo apt-get update2:安装相关软件 sudo apt-get install vim openssl build-essential libssl-dev wget ...

  4. iOS原生APP和H5交互-delegate和第三方

    一.原生代码中直接加载页面(拦截) 1.    具体案例 加载本地/网络HTML5作为功能介绍页 2.    代码示例 //本地 -(void)loadLocalPage:(UIWebView*)we ...

  5. 封装framework注意点

    1.新建一个framework过程: . 2.在工程内新建一些类,注意,使用xib时初始化必须要加上loadnib:,否则会造成xib无效(可能是因为没有加载) 如下: JFViewControlle ...

  6. WCF之maxConnections

    <bindings> <netTcpBinding> <binding name="TcpBinding" closeTimeout="00 ...

  7. Maven 项目管理从未如此通畅

    一,写在前面 Maven到底是什么?它能做些什么?能为我们的开发工作提供什么样的帮助?为什么会有如此大的知名度?另外,常听大厂的人说“私服”,工具管理吧啦吧啦的一堆也是不明觉厉.相信仁者见仁,着智者见 ...

  8. HTML5新增的form属性简介——张鑫旭

    一.引言 HTML5中新增了一个名为form的属性,是一个与处理表单相关的元素. 在HTML4或XHTML中,我们要提交一个表单,必须把相关的控件元素都放在<form>元素下.因为表单提交 ...

  9. css-图文案例

    效果如下: 附上代码: <html> <head> <title>World</title> <style type="text/css ...

  10. [HNOI2004]宠物收养场

    fhq treap 开俩哨兵节点,然后插入.删除.前驱.后继,统计即可 #include"cstdio" #include"cstring" #include& ...