• Shell中, 退出整个脚本


    常规做法

    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信号,这样就可以让整个脚本退出了!

    个人主页: http://www.lslxdx.com
  • 相关阅读:
    SpringMVC中web.xml中url配置路径 / 和 /* 的区别
    spring mvc @RequestMapping method 不写的话,默认GET、POST都支持,根据前端方式自动适应
    MyBatis项目所引用的一切依赖jar包和自定义设置
    Python 代码性能优化技巧
    linux basic commands
    linuxx virutal machine installation
    安装 Django
    virtualenv (isolated virtual environment) for python runtime
    夜间模式的开启与关闭,父模板的制作
    完成登录与注册页面的前端
  • 原文地址:https://www.cnblogs.com/lslxdx/p/6566465.html
Copyright © 2020-2023  润新知