Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why does `timeout 2 timeout 1 bash` stuck

I am studying the timeout command in Linux shell.

When I try timeout 1 bash, bash will run and will be killed after 1 second.

When I try timeout 2 timeout 1 yes, the program yes will run for 1 second and be killed by the second timeout.

But when I try timeout 2 timeout 1 bash, it is stuck. No bash shell appears and it keep running even if I press Ctrl+C.

I know that it is not useful to write two timeout in one command.

I only wonder why this will happen.

like image 524
zzh1996 Avatar asked Oct 29 '22 15:10

zzh1996


1 Answers

Here's another example of the same behavior:

strace timeout 1 bash Even if you interrupt the strace, bash will continue running.

If we strace the bash process itself in the same time, we notice the following looping.

--- 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

Now, according to http://www.gnu.org/software/libc/manual/html_node/Job-Control-Signals.html

Macro: int SIGTTIN

A process cannot read from the user’s terminal while it is running as a background job. When any process in a background job tries to read from the terminal, all of the processes in the job are sent a SIGTTIN signal. The default action for this signal is to stop the process. For more information about how this interacts with the terminal driver, see Access to the Terminal.

timeout 2 timeout --foreground 1 bash works, because the inner timeout will allow it to work with the tty, although it is not run directly from the interactive 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

We can chain as many timeouts as we want, as long as all but the one ran from the interactive shell are with the --foreground option:

timeout 3 timeout --foreground 2 timeout --foreground 1 bash

Also check the SIGNALS section in man bash for more info on how bash reacts to the various signals in different cases.

like image 116
dgeorgiev Avatar answered Nov 15 '22 07:11

dgeorgiev