Home > database >  Linux cat command and errors
Linux cat command and errors

Time:01-29

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 HELLO text
  • $1 (first argument) is b.txt which 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 HELLO text
  • $1 (first argument) is b.txt which 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, arg3 respectively
  • 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 use cat < data.txt
  •  Tags:  
  • Related