I was trying linux redirection. I have a directory where there is just one file - a.txt
more a.txt
HELLO
If I type
cat < a.txt b.txt , I get
cat: b.txt: No such file or directory
If I type
cat < a.txt b.txt a.txt
I get
cat: b.txt: No such file or directory
HELLO
Why am I not seeing HELLO when I try cat < a.txt b.txt? I tried different combinations - typing a.txt multiple times before/after b.txt and see a pattern, but not able to figure out why.
cat < a.txt a.txt b.txt
HELLO
cat: b.txt: No such file or directory
CodePudding user response:
I assume you don't use cat the right way. Cat expects a file or many files as parameter not an data stream.
To show the file with cat use:
cat a.txt
To Redirect it into file b.txt
cat a.txt > b.txt
And your last question, with the pattern.
You pass 3 arguments to cat.
Arg1: (< a.txt)
Arg2: (a.txt)
Arg3: (b.txt)
Argument 1 is nonsense Argument 2 a valid file and Arg 3 an incorrect file.
CodePudding user response:
< inputfile is a redirection. < redirects the file inputfile into stdin standard input of a command. The < and inputfile are not passed as arguments to the command. The placement doesn't matter, these lines are all exactly the same:
< inputfile command arg1 arg2
command < inputfile arg1 arg2
command arg1 < inputfile arg2
command arg1 arg2 < inputfile
Why am I not seeing HELLO when I try cat < a.txt b.txt?
From man cat:
With no FILE, or when FILE is -, read standard input.
Because given arguments, cat is not reading from stdin - stdin is ignored. Instead it reads from given FILEs on arguments. So a.txt on stdin is ignored.
You can do:
< a.txt cat - b.txt
# or
cat - < a.txt b.txt
# or
cat - b.txt < a.txt
# or really just
cat a.txt b.txt
CodePudding user response:
Redirecting means sending the content of the file into the command's STDIN.
cat's behavior is to read content of file in it's argument(s) to STDOUT. But if there's no argument, then the content is read from STDIN.
See that I write argument(s) there? It's because the number of argument can be 0, 1, or multiple.
in simple pseudocode, it's like this:
if number of arguments = 0
print STDIN to STDOUT
else
for each file in arguments
print file content to STDOUT
Example 1:
cat a.txt
output:
HELLO
Example 2:
cat (then enter)
You will be able to type into terminal, when you click enter, the typed line is sent to cat's STDIN. Then cat will print line you just typed.
Answer
So when you type:
cat < a.txt b.txt
internally, it works like this:
- STDIN is filled with content of a.txt
HELLOtext - $1 (first argument) is
b.txtwhich is a non-existent file
based on behavior above, it will print content of b.txt alone since there is 1 argument supplied.
but it doesn't find file b.txt, so it outputs an error message.
when you type:
cat < a.txt b.txt a.txt
internally, it works like this:
- STDIN is filled with content of a.txt
HELLOtext - $1 (first argument) is
b.txtwhich is a non-existent file - $2 (second argument) is
a.txt
will output: (once again STDIN is ignored because there are 2 arguments)
cat: b.txt: No such file or directory
HELLO
More detailed explanation
- when you run command
mycommand arg1 arg2 arg3, it means there are 3 command line arguments:arg1,arg2,arg3respectively - STDIN is standard input: data stream for sending input to a command. You can send data to STDIN like these (assuming the target command is
cat):echo "my data" | cat- make file called data.txt, filled with
my data, save it, then usecat < data.txt
