Shell 编写脚本时SIGSTOP不起作用

Shell 编写脚本时SIGSTOP不起作用,shell,kill,raise,Shell,Kill,Raise,我有一个非常庞大的档案,必须一个文件一个文件地提取出来,然后进一步处理。我没有足够的内存来提取整个归档文件(无论是在RAM中还是闪存中),因此我编写了一个小应用程序,在每次提取文件后停止(raise(SIGSTOP))。等效代码可以是以下代码: #include <stdio.h> #include <signal.h> int main() { printf("started.\n"); fflush(stdout); sleep(2);

我有一个非常庞大的档案,必须一个文件一个文件地提取出来,然后进一步处理。我没有足够的内存来提取整个归档文件(无论是在RAM中还是闪存中),因此我编写了一个小应用程序,在每次提取文件后停止(
raise(SIGSTOP)
)。等效代码可以是以下代码:

#include <stdio.h>
#include <signal.h>

int main() {
    printf("started.\n"); fflush(stdout);
    sleep(2);                             // extracting archive
    printf("stopping\n"); fflush(stdout);
    raise(SIGSTOP);                       // stopping
    printf("resume + done\n"); fflush(stdout);
    return 0;
}
但是当从脚本调用该方法时,该命令永远不会返回:

$ cat doit.sh 
#!/bin/sh
echo "STARTING"
./dosleep
echo "BACK"
$ ./doit.sh 
STARTING
started.
stopping

^C^C^C^C^C^C
为什么终端和脚本的行为如此不同?有没有办法改变这种行为


谢谢,在非交互式shell中,作业控制默认为关闭,但您可以显式启用它:

set -m
因此,如果我们修改脚本,在shebang上添加
set-m
行或
-m
,如下所示:

#!/bin/bash -m
./start-delay
echo BACK
…然后,
停止后,
返回


引用bash手册页中的话,emphasis补充道:

-m
监控模式。作业控制已启用。默认情况下,对于支持此选项的系统上的交互式Shell,此选项处于启用状态(请参见上面的作业控制)。所有进程都在单独的进程组中运行。后台作业完成后,shell将打印一行,其中包含其退出状态


当不是从登录shell调用脚本时,您必须使用
setsid sh-c'myscript.sh
启动脚本,否则您将得到
无法访问tty;作业控制关闭了
@Charly,…嗯,与其说是“不是来自登录shell”,不如说是“来自没有TTY的地方”。这两者有点正交——可能有一个没有TTY的登录shell,或者有一个没有登录shell的TTY。
#!/bin/bash -m
./start-delay
echo BACK