我正在研究Linux shell中的timeout
命令。
当我尝试timeout 1 bash
时,bash将会运行并在1秒后被杀死。
当我尝试timeout 2 timeout 1 yes
时,程序yes
将运行1秒钟,并被第二个timeout
杀死。
但是当我尝试timeout 2 timeout 1 bash
时,它会被卡住。没有bash shell出现,即使按Ctrl + C也会继续运行。
我知道在一个命令中编写两个timeout
没用。
我只是想知道为什么会这样。
答案 0 :(得分:2)
以下是同一行为的另一个例子:
strace timeout 1 bash
即使你打断了strace,bash也会继续运行。
如果我们在同一时间内对bash进程进行了分析,我们会注意到以下循环。
--- SIGTTIN {si_signo = SIGTTIN,si_code = SI_USER,si_pid = 7162,si_uid = 1000} --- rt_sigaction(SIGTTIN,{sa_handler = SIG_IGN, sa_mask = [],sa_flags = SA_RESTORER,sa_restorer = 0x7f097723a7e0}, {sa_handler = SIG_DFL,sa_mask = [],sa_flags = SA_RESTORER, sa_restorer = 0x7f097723a7e0},8)= 0 ioctl(255,TIOCGPGRP,[6412])
= 0 rt_sigaction(SIGTTIN,{sa_handler = SIG_DFL,sa_mask = [],sa_flags = SA_RESTORER,sa_restorer = 0x7f097723a7e0}, {sa_handler = SIG_IGN,sa_mask = [],sa_flags = SA_RESTORER, sa_restorer = 0x7f097723a7e0},8)= 0 kill(0,SIGTTIN) = 0
现在,根据http://www.gnu.org/software/libc/manual/html_node/Job-Control-Signals.html
宏:int SIGTTIN
当进程作为后台作业运行时,进程无法从用户终端读取。当后台作业中的任何进程尝试时 从终端读取,作业中的所有进程都被发送了 SIGTTIN信号。此信号的默认操作是停止 处理。有关它如何与之交互的更多信息 终端驱动程序,请参阅访问终端。
timeout 2 timeout --foreground 1 bash
有效,因为内部超时将允许它与tty一起使用,尽管它不是直接从交互式shell运行。
man timeout
--foreground
when not running timeout directly from a shell prompt,
allow COMMAND to read from the TTY and get TTY signals; in this mode, children of COMMAND will not be timed out
我们可以根据需要链接尽可能多的超时,只要从交互式shell运行的所有超时都使用--foreground
选项:
timeout 3 timeout --foreground 2 timeout --foreground 1 bash
另请查看SIGNALS
中的man bash
部分,了解更多信息,了解bash在不同情况下如何对各种信号作出反应。