函数内部的bash退出脚本 [英] bash exit script from inside a function

查看:60
本文介绍了函数内部的bash退出脚本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在某些情况下,您想从函数内部终止脚本:

There are situations where you want to terminate the script from inside a function:

function die_if_fatal(){
    ....
    [ fatal ] && <termination statement>
}

如果脚本是源文件,则 $.脚本,终止语句为:

If the script is sourced, $ . script, and the termination statement is:

    如预期的那样,
  • return 将从 die 返回,但不会完成脚本
  • exit 终止会话(不返回脚本).
  • return, as expected, will return from die, but will not finish the script
  • exit terminate the session (doesn't return to the script).

现在,如果执行了脚本: chmod + x script;./script:

Now, if the script is executed: chmod +x script; ./script:

    如预期的那样,
  • return 将从 die 返回,但不会完成脚本
  • 退出不会返回到 die 并终止脚本.
  • return, as expected, will return from die, but will not finish the script
  • exit doesn't return to die and terminate the script.

简单的方法是使用返回码并在返回时检查它们,但是,我需要停止父级,而无需修改调用者脚本.

The simple method is to use return codes and check them upon return, however, I need to stop the parent, without modifying the caller script.

有多种方法可以解决此问题,但是,假设您已进入复杂脚​​本的第5级,并且发现该脚本必须结束;也许是一个魔术"退出代码?我只希望对源代码执行行为.

There are alternatives to handle this, however, imagine you are 5 level into a complex script and you find that the script must end; maybe a 'magic' exit code? I just want the execute behavior on a sourced code.

我正在寻找一个简单的语句,以结束正在运行的源脚本.

I'm looking for a simple one statement, to end a running sourced script.

采购时,从函数内部完成脚本的正确方法是什么?

When sourcing, what is the right method to finish the script from inside a function?

推荐答案

我的想法是基于 PGID (进程组标识符)和 SID (会话标识符).除非您直接从会话负责人那里获取脚本,否则以下解决方案将起作用.另一方面,会话负责人主要是守护程序和交互式外壳程序.您可以通过 ps aux |验证哪些进程作为会话领导者运行.awk'$ 8〜/s/{print}'.

My idea is to base on PGID (Process Group Identifier) and SID (Session identifier). Unless you source your script directly from a session leader, the following solution works. On the other hand, session leaders are mostly daemons and interactive shells. You can verify which processes run as session leaders by ps aux | awk '$8 ~ /s/ { print }'.

/tmp/my_quit.sh :

get_pid()
{
    pgid=$( ps -q $$ -o pgid= )
    sid=$( ps -q $$ -o sid= )
    if [[ $pgid == $sid ]]; then
        echo 0
    else
        echo $pgid
    fi
}

fatal()
{
    echo "1"
}

die_if_fatal()
{
    if [ $(fatal) -ne 0 ]; then
        pid=$( get_pid )
        if [ $pid -ne 0 ]; then
            echo "      >> Kill $pid"
            kill $pid
        else
            return
        fi
    fi
    echo "Rest of die_if_fatal's logic"
}

die_if_fatal
echo "      >> Sourced from a session leader. Will not end the process."

/tmp/pack1.sh :

echo "$0: PID: $$ PGID: $( ps -q $$ -o pgid= ) SID=$( ps -q $$ -o sid= )"
echo "  >> Sourcing my_quit..."
. /tmp/my_quit.sh
echo "  >> Executing my_quit..."
/tmp/my_quit.sh

/tmp/pack2.sh :

echo "$0: PID: $$ PGID: $( ps -q $$ -o pgid= ) SID=$( ps -q $$ -o sid= )"
echo "Sourcing pack1..."
. /tmp/pack1.sh
echo "Executing pack1"
/tmp/pack1.sh

用例

直接从外壳执行die_if_fatal(my_quit.sh)-上面没有脚本

执行脚本:

[kan@pckan ~]$ /tmp/my_quit.sh 
      >> Kill 11360
Finished
[kan@pckan ~]$

获取脚本:

[kan@pckan ~]$ . /tmp/my_quit.sh 
      >> Sourced from a session leader. Will not end the process.
[kan@pckan ~]$ 

pack1.sh 执行-1级嵌套

从外壳执行 pack1.sh :

[kan@pckan ~]$ /tmp/pack1.sh 
/tmp/pack1.sh: PID: 11260 PGID: 11260 SID= 1630
  >> Sourcing my_quit...
      >> Kill 11260
Finished
[kan@pckan ~]$

从shell中采购 pack1.sh :

[kan@pckan ~]$ . /tmp/pack1.sh 
/bin/bash: PID: 1630 PGID:  1630 SID= 1630
  >> Sourcing my_quit...
      >> Sourced from a session leader. Will not end the process.
  >> Executing my_quit...
      >> Kill 11316
Finished
[kan@pckan ~]$

pack2.sh 执行-2个(可能还有更多)嵌套级别

从shell执行pack2.sh:

Executing from pack2.sh - 2 (and possibly more) levels of nesting

Executing pack2.sh from shell:

[kan@pckan ~]$ /tmp/pack2.sh
/tmp/pack2.sh: PID: 11535 PGID: 11535 SID= 1630
Sourcing pack1...
/tmp/pack2.sh: PID: 11535 PGID: 11535 SID= 1630
  >> Sourcing my_quit...
      >> Kill 11535
Finished
[kan@pckan ~]$ 

从shell中采购pack2.sh:

Sourcing pack2.sh from shell:

[kan@pckan ~]$ . /tmp/pack2.sh
/bin/bash: PID: 1630 PGID:  1630 SID= 1630
Sourcing pack1...
/bin/bash: PID: 1630 PGID:  1630 SID= 1630
  >> Sourcing my_quit...
      >> Sourced from a session leader. Will not end the process.
  >> Executing my_quit...
      >> Kill 11618
Finished
Executing pack1
/tmp/pack1.sh: PID: 11627 PGID: 11627 SID= 1630
  >> Sourcing my_quit...
      >> Kill 11627
Finished
[kan@pckan ~]$ 

这篇关于函数内部的bash退出脚本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆