在交互式bash shell中,我想调用一个函数,
它启动一个子shell,以运行一些bash代码
f() { echo a; ( sleep 5; ); echo z $?; }; f
我需要潜艇来接
exit 1
根据bash代码,
所以我的交互式bash shell一直在运行。
另请参阅
Is there a TRY CATCH command in Bash
例如,子shell中的代码是一个长时间运行的进程
sleep 5
问题:当我调用函数并发送SIGTSTP(Ctrl-Z)时,
然后只有子shell停止,主函数继续运行
预期:SIGTSTP(Ctrl-Z)应该停止主函数和子shell,
和SIGCONT(fg)应继续同时运行
解决方法:
build bash with --disable-job-control
,
因为
set +m
不起作用,并且
stty susp undef
限制性太强
$ f() { echo a; ( sleep 5; ); echo z $?; }; f
a
^Z
[1]+ Stopped ( sleep 5 )
z 148
$ fg
( sleep 5 )
$
返回代码148表示128+20,并且20==SIGTSTP
另请参阅
Exit status ($?) of 148 upon Ctrl+Z
具有
wait -f %1
在主要功能中,
主函数挂起,我不得不中断(Ctrl-C)
%1
在这里工作,因为只有一份工作
$ f() { echo a; ( sleep 5; ); wait -f %1; echo z $?; }; f
a
^Z
[1]+ Stopped ( sleep 5 )
bash: warning: wait_for_job: job 1 is stopped
^Z^Z^Z^Z^Z^Z^C
$
具有
trap "" SIGTSTP
在子shell中,SIGTSTP(Ctrl-Z)被忽略
$ f(){ echo a; ( trap "" SIGTSTP; sleep 5; ); echo z $?; }; f
a
^Z^Z^Z^Z^Z^Z^Zz 0
$
具有
trap handle_tstp SIGTSTP
在潜艇外壳中,
交互式shell挂在SIGTSTP(Ctrl-Z)上
$ f(){ echo a; ( s() { echo s; }; trap s SIGTSTP; sleep 5; ); echo z $?; }; f
a
^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^C^C^C^C^C^C^C^C^C^C^C^C^C
陷阱句柄_tstp SIGTSTP
在主要功能中没有效果
f(){ s() { echo s; }; trap s SIGTSTP; echo a; ( sleep 5; ); echo z $?; }; f
kill -SIGTSTP $$
在主要功能中没有效果,
所以主功能无法自行停止
f(){ echo a; ( sleep 5; ); kill -SIGTSTP $$; echo z $?; }; f
$$
对
$BASHPID
,父shell与子shell
$ f(){ echo par $$ $BASHPID; ( echo sub $$ $BASHPID; ) }; f
par 613627 613627
sub 613627 613652
我尝试了更多的技巧。。。但是SIGTSTP总是只停止一部分并且另一部分保持在后台运行。我还试图手动捕获SIGTSTP
kill -SIGTSTP $subshell_pid
但是陷阱无法捕获SIGTSTP
这样,SIGTSTP将被忽略
r() { echo $$.b; while read -r L; do echo "$$.b $L"; done <$1; echo $$.d; }; f() { echo $$.a; r <( for ((i=0;i<5;i++)); do echo $BASHPID.c.$i; sleep 1; done; ); echo $$.z $?; }; f
有了这些,SIGTSTP只停止前台进程
r() { echo $$.b; cat $1 | while read -r L; do echo "$$.b $L"; done; echo $$.d; }; f() { echo $$.a; r <( for ((i=0;i<5;i++)); do echo $BASHPID.c.$i; sleep 1; done; ); echo $$.z $?; }; f
r() { echo $$.b; cat $1; echo $$.d; }; f() { echo $$.a; r <( for ((i=0;i<5;i++)); do echo $BASHPID.c.$i; sleep 1; done; ); echo $$.z $?; }; f
r() { echo $$.b; t() { echo trap; }; trap t SIGTSTP; cat $1 | while read -r L; do echo "$$.b $L"; done; echo $$.d; }; f() { echo $$.a; r <( for ((i=0;i<5;i++)); do echo $BASHPID.c.$i; sleep 1; done; ); echo $$.z $?; }; f
另请参阅:
Why does a subshell of an interactive shell run as an interactive shell?
子shell继承父级的所有特性