函数内部的bash退出脚本 [英] bash exit script from inside a function
问题描述
在某些情况下,您想从函数内部终止脚本:
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 scriptexit
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 scriptexit
doesn't return todie
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屋!