Hey I have been researching this for a while and I was wondering if someone can explain the mechanism of this particular feature on the bash shell.
Lets say we have 3 files: test1.txt
, test2.txt
, and test3.txt
.
Contents of each file:
test1.txt
= "foo"
test2.txt
= "bar"
test3.txt
= "hello world"
if we run the following command on bash shell: cat < test1.txt test2.txt test3.txt
we would get:
bar
hello world
My question is why the contents of test1.txt
ignored in this case, and if anyone has any good sources I can read up on this particular feature.
CodePudding user response:
The input redirection is processed before identifying arguments. The command you show, for example, is equivalent to each of
< test1.txt cat test2.txt test3.txt
cat test2.txt < test1.txt test3.txt
cat test2.txt test3.txt < test1.txt
In any case, you are left with cat
's standard input being test1.txt
, and it receiving two command-line arguments test2.txt
and test3.txt
.
cat
, however, only reads from its standard input if it has no arguments naming input files. If you want to read from both standard input and named files, use -
as the "name" of standard input.
# Same result as cat test1.txt test2.txt test3.txt
cat - test2.txt test3.txt < test1.txt
CodePudding user response:
By default, cat
(like most utilities) only reads from standard input if it has no filename arguments. Since you're passing test2.txt
and test3.txt
as filenames, it ignores the input redirection.
However, you can use -
as an argument to mean standard. So you can do:
cat - test2.txt test3.txt < test1.txt
This isn't very useful when you're redirecting from a file, since you could just provide the filename as a normal argument instead of using redirection, but it can be useful when piping:
grep foo test1.txt | cat - test2.txt test3.txt