我的想法是基于PGID(进程组标识符)和SID(会话标识符)。除非您直接从会话领导者获取脚本,否则以下解决方案适用。另一方面,会话领导者大多是守护进程和交互式 shell。您可以通过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
使用案例
直接从Shell中执行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级
从shell执行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执行 - 两个(可能更多)嵌套级别
从shell执行pack2.sh:
[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的来源:
[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 ~]$