Search code examples
bashshellfilehttp-redirectcommand-substitution

Why does input redirection work differently when in command substitution?


Consider the following case:

$ echo "abc" > file
$ var=$(< file)
$ echo "$var"
abc

Inside the command substitution, we use a redirect and a file, and the content of the file is correctly captured by the variable.

However, all the following examples produce no output:

$ < file
$ < file | cat
$ < file > file2
$ cat file2

In all these cases the content of the command is not redirected to the output.

So why is there a difference when the redirect is placed inside the command substitution or not? Does the redirect have a different function when inside vs outside a command substitution block?


Solution

  • $(< file) is not a redirection; it is just a special case of a command substitution that uses the same syntax as an input redirection.

    In general, an input redirection must be associated with a command. There is one case that arguably could be considered an exception, which is

    $ > file
    

    It's not technically a redirection, since nothing is redirected to the file, but file is still opened in write mode, which truncates it to 0 bytes.