1

Say I run a pipeline from a terminal:

$ a | b

is there a way for me to send a signal from the terminal to both processes, or can stdin from the terminal only be read from one of the two processes?

Note I can read from stdin from b by using something like:

open /dev/tty

but that appears to prevent a from reading from stdin, from my testing. Why?

Basically when I send ctrl-c or ctrl-d to the pipeline, and I am reading from stdin in b, then a will not get the signal (according to my testing).

  • Your last comment is different from your question. A ^- sequence doesn't go through the standard input. Either the terminal or the shell (I don't know) turns it into a signal and sends it to the running process. – giusti Jul 24 '19 at 23:34
  • From my testing a signal comes from stdin, and can only be capture by something reading from stdin – Alexander Mills Jul 25 '19 at 0:56
2
  1. You need to clarify that signals like Ctrl-C are NOT passed through stdin. When you type Ctrl-C on your terminal, the "Ctrl" and "C" are not directly passed to your process as 2 raw characters, the tty driver interprets them as signal SIGINT and send the signal to your foreground process group.

  2. If you type Ctrl-C when a | b is running, BOTH of the 2 processes will receive the signal SIGINT. To test this, you can type Ctrl-C while this command are running:

tail -f /var/log/syslog | grep some_pattern

and you will see the shell prompt immediately, which means both processes interrupted.

And how's that?

  • After you logged-in a shell, you are in a session, all programs ran in the shell are own by this session.

  • A session can have a controlling terminal, it generally take input from your keyboard and output to your screen. Processes in this session read stdin from the controlling terminal, write stdout and stderr to the controlling, and receive signals from the controlling terminal.

  • Processes linked with shell pipe forms a process group. e.g.:

proc1 | proc2 &

or like

proc3 | proc2 | proc5
  • A session can have one foreground process group and one or more background process groups. The process group blocking your shell and taking your foreground screen is the foreground process group. While the process group ran by & will be a background process group.

  • Whenever you type sequences like "Ctrl-C" in the controlling terminal, the signal will be sent to all processes in the foreground process group.

1

You are mixing a lot of things, standard input,output,error file descriptors (fds) are not the same thing as the terminal fd.

When you open a terminal and enter a command, by default those 3 fds (stdin (0),stdout(1),stderr(2)) "point" to the terminal, but that can be changed by redirecting any of those fds (for example "ls non_existing_file 2>err" will redirect the error messages to the file "err" and you will not see it on the terminal).

Now i would like to address your "open /dev/tty" line, that actually points to your TERMINAL, to demonstrate the difference, check out this sample program. enter image description here To put how piping works simply:

When you pipe two commands (without any "<" or ">"), the first command will take its input from the keyboard (if it requires reading input) and will redirect its output to be taken as input by the second command, that means that the "standard" input of your process "b" is no longer the terminal, but the output of the process "a".

From Wikipedia

Now to finally answer your question you need to know 2 more things:

1) When you launch a process into the foreground, the shell will give that process control of terminal and it will wait until the process is finished to take back control of the terminal, and any keyboard-generated signals will be sent to that controlling process during its execution.

2) When you launch a piped command (cmd1 | cmd2), the shell will first put those 2 process in the same "process group" (If you want to know more, read about job control). So what happens with your "a | b" is that these 2 process are in the same process group, so any keyboard-generated signals will be sent to BOTH those processes. because keyboard-generated signals are sent to a whole process group and NOT a single process. I hope this answers your question, don't hesitate to ask question if anything is not clear

  • Good answer, especially the part about keyboard-generated signals. +1 already. Maybe worth adding a note regarding pipe being a pair of file descriptors, that are technically shared between two processes (though for left command read fd is closed and for right command write fd is closed). – Sergiy Kolodyazhnyy Nov 2 '19 at 3:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.