我有一个非常庞大的存档,必须逐个文件提取并进一步处理。我没有足够的内存来提取整个存档(无论是在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;
}
当我在终端中执行此操作时,这工作正常:
$ gcc -o dosleep main.c
$ ./dosleep
started.
stopping
[1]+ Stopped ./dosleep
$ fg
./dosleep
resume + done
$
但是从脚本调用方法时,命令永远不会返回:
$ cat doit.sh
#!/bin/sh
echo "STARTING"
./dosleep
echo "BACK"
$ ./doit.sh
STARTING
started.
stopping
^C^C^C^C^C^C
为什么终端和脚本的行为如此不同?有没有办法改变这种行为?
谢谢,卡尔
答案 0 :(得分:1)
非交互式shell中的作业控制是非默认的,但您可以显式启用它:
set -m
因此,如果我们修改您的脚本,以便在shebang上添加set -m
行或-m
,如下所示:
#!/bin/bash -m
./start-delay
echo BACK
...然后在BACK
之后发出stopping
。
引自bash手册页section on set
,重点补充:
-m
监控模式。作业控制已启用。 默认情况下,对于支持它的系统上的交互式shell,此选项处于启用状态(请参阅上面的JOB CONTROL)。所有进程都在一个单独的进程组中运行。后台作业完成后,shell会打印一行包含退出状态的行。