Quantcast
Channel: User Kamil Maciorowski - Super User
Viewing all articles
Browse latest Browse all 645

Answer by Kamil Maciorowski for How does exec interact with pipes in shells?

$
0
0

It means, if I understand correctly, that all commands trying to read from stdin will actually read from file

A command reading from its stdin will read from a regular file if its stdin happens to be the regular file. A command reading from its stdin will read from a terminal or from a fifo (which are also files) if its stdin happens to be the terminal the fifo respectively.

Stdin of one command can be different than stdin of another command.

In a script interpreted by bash, exec < file redirects the stdin of this particular bash process only. Later commands will be affected if they inherit stdin, but the inheritance happens in the same way regardless if you used exec < file or not.

If you run just cmd0 then it will inherit stdin and stdout (and stderr) from the interpreting bash. It's irrelevant what the stdin and stdout of the interpreting bash are; the mechanism is always the same.

If you run cmd1 | cmd2 | … | cmdN then cmd1 will inherit stdin from the interpreting bash and cmdN will inherit stdout from the interpreting bash. Other stdins and stdouts will form a pipeline (stdout of cmd1 connected to stdin of cmd2 and so on). It's irrelevant what the stdin and stdout of the interpreting bash are; the mechanism is always the same.

The fact you used exec < file is irrelevant to the mechanism itself. Some command(s) will inherit stdin and/or stdout from the interpreting bash. Without exec < file they would inherit something. With exec < file they will inherit something else as stdin.

This means exec < file can affect some commands, but only commands that inherit stdin from the interpreting bash. Your cmd1 does inherit the stdin of the interpreting bash, but cmd2 does not.

Assuming your cmd2 simply reads from its stdin, it will read from the output of cmd1. The prior exec < file doesn't matter. (Note in general cmd2 may redirect or ignore or close its stdin; commands designed to work in pipelines don't do this, unless told to.)

You can test this in a script:

#!/bin/bash# Don't run this in an interactive shell. Run as a script.exec < /etc/fstabecho foo | catwc -l

Note if you paste the above code in an interactive bash then you will change the stdin of the bash itself and it will eventually exit upon EOF. For your convenience below is a version that can be run in an interactive shell without terminating it:

bash -c '   exec < /etc/fstab   echo foo | cat   wc -l'

The output should be foo (proving cat reads the output of echo) followed by a number being the number of lines in your fstab (proving wc reads from fstab).


Viewing all articles
Browse latest Browse all 645

Trending Articles