The mechanics of this shell syntax: ${1:-$(</dev/stdin)}
$(
..)
: from bash manual is a command substitution not process substitution<(
..)
. and from Command substitution
The command substitution $(cat file) can be replaced by the equivalent but faster $(< file).
/dev/stdin
is a symlink to/proc/self/fd/0
, convenient here because of$(<
..)
syntax which expects a file.this could cause a problem because the command may be blocked until stdin closed. it is safe in the meaning that multiline input will be preserved because au double-quotes.
Finally creating a pipe and forking a process (like in mv -v foo.ext bar.ext | log
) for each log command may be inefficient.
Answering your questions
- You have confused the syntax between using process substitution which takes the syntax of
<(cmd)
and simple shell re-direction< file
. In plain form,<
basically is to read from the standard input and>
to write to standard output. The syntax< file
is a short-hand syntax to put the contents of thefile
made available on the standard input which can be read by the commands. - So when you run
cat < file
, it basically puts the content of thefile
in standard input file descriptor which is later thanread
by thecat
process. The advantage of using$(<file)
would be the shell doesn't have fork an external processcat
and just use its own mechanism to read the file content. - The
$(..)
is a syntax for command-substitution where command is run in a sub-shell environment and$(..)
is replaced with the standard output of the command. For a special case of"$(<file)"
i.e. without any commands and only re-directions involved, the shell instead of reading from the standard input starts reading from the start of the file and puts the result on the standard output.