bash 中的 SIGINT 和进程替换
SIGINT and process substitution in bash
我发现如果我有类似的东西:
#!/usr/bin/env bash
function abort-politely {
echo 'Aborting politely'
{
sleep 5
touch .stop
}
}
trap 'abort-politely' SIGINT
{
while [ ! -r .stop ] ; do echo hello world ; sleep 1 ; done
rm -f .stop
} &
wait $!
echo Exiting
它的行为符合我的预期,也就是说后台任务在中断后继续5s:
hello world
hello world
hello world
hello world
<Ctrl+C pressed>
Aborting politely
hello world
hello world
hello world
hello world
hello world
Exiting
但是,如果我引入 process substitution 作为后台进程的一部分...
#!/usr/bin/env bash
function abort-politely {
echo 'Aborting politely'
{
sleep 5
touch .stop
}
}
trap 'abort-politely' SIGINT
{
# The "while" loop below is all that has changed
while [ ! -r .stop ] && read line; do echo hello $line ; done < <(
while : ; do echo world ; sleep 1 ; done
)
rm -f .stop
} &
wait $!
echo Exiting
...当按下Ctrl+C时,后台进程似乎立即退出:
hello world
hello world
hello world
hello world
<Ctrl+C pressed>
Aborting politely
<5 seconds delay>
Exiting
我原以为会得到与第一种情况相同的输出。
为什么这没有像我预期的那样工作?有没有办法让它表现得像我希望的那样?我想我需要的是让进程替换继续进行,直到它不再被读取为止。 (我想知道在进程替换块中添加 trap '' SIGINT
是否可能是解决方案,但它会立即退出。)
SIGINT 信号通过子进程传播,导致进程替换 shell 自行中止。
您可以通过添加 trap : SIGINT
:
来避免它
while [ ! -r .stop ] && read line; do echo hello $line ; done < <(
trap : SIGINT
while : ; do echo world ; sleep 1 ; done
)
我发现如果我有类似的东西:
#!/usr/bin/env bash
function abort-politely {
echo 'Aborting politely'
{
sleep 5
touch .stop
}
}
trap 'abort-politely' SIGINT
{
while [ ! -r .stop ] ; do echo hello world ; sleep 1 ; done
rm -f .stop
} &
wait $!
echo Exiting
它的行为符合我的预期,也就是说后台任务在中断后继续5s:
hello world
hello world
hello world
hello world
<Ctrl+C pressed>
Aborting politely
hello world
hello world
hello world
hello world
hello world
Exiting
但是,如果我引入 process substitution 作为后台进程的一部分...
#!/usr/bin/env bash
function abort-politely {
echo 'Aborting politely'
{
sleep 5
touch .stop
}
}
trap 'abort-politely' SIGINT
{
# The "while" loop below is all that has changed
while [ ! -r .stop ] && read line; do echo hello $line ; done < <(
while : ; do echo world ; sleep 1 ; done
)
rm -f .stop
} &
wait $!
echo Exiting
...当按下Ctrl+C时,后台进程似乎立即退出:
hello world
hello world
hello world
hello world
<Ctrl+C pressed>
Aborting politely
<5 seconds delay>
Exiting
我原以为会得到与第一种情况相同的输出。
为什么这没有像我预期的那样工作?有没有办法让它表现得像我希望的那样?我想我需要的是让进程替换继续进行,直到它不再被读取为止。 (我想知道在进程替换块中添加 trap '' SIGINT
是否可能是解决方案,但它会立即退出。)
SIGINT 信号通过子进程传播,导致进程替换 shell 自行中止。
您可以通过添加 trap : SIGINT
:
while [ ! -r .stop ] && read line; do echo hello $line ; done < <(
trap : SIGINT
while : ; do echo world ; sleep 1 ; done
)