Shell 编写脚本时SIGSTOP不起作用
我有一个非常庞大的档案,必须一个文件一个文件地提取出来,然后进一步处理。我没有足够的内存来提取整个归档文件(无论是在RAM中还是闪存中),因此我编写了一个小应用程序,在每次提取文件后停止(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);
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