Question

I tried the following command $cat < text > text where text is a non-empty file. There was no output to stdout and the file text became blank. I expected cat command to read the file text and output the contents to the same file.

However when I try $cat < text > newtext it works! newtext is a copy of text.

Another doubt, When I try $cat < text >>text where >> usually appends to a file. My terminal gets stuck in an infinite loop and file text is repeatedly appended to itself. Why does this happen?

Was it helpful?

Solution

You cannot use the same file as stdin and stdout. Why? Because all commands are executed at the same time, and the shell prepares redirections before executing the commands. Hence, the output file is emptied before executing.

Instead, you have to use temporary files.

A workaround could be your solution or also:

cat text > newtext && mv newtext text

OTHER TIPS

When you redirect your output to a file with

echo "something" > file.txt

the first thing that happens, is that your file is (re)created. If it exists, it will be emptied and that's exactly what you see.

You can show the contents of the file by simply invoking

cat file.txt

To achieve what you've tried, you could do

cat file.txt > temp.txt && mv temp.txt file.txt

but I don't see a reason why you would want to do that.

If you think about it the shell has to do the redirections first. If the shell actually executed the command from left to right as you expect then cat file would display the files contents to the terminal then the shell would see > file and have to back track i.e. clear the output from the terminal and rerun the command with the stdout redirected.

This obviously doesn't make sense so when the shell parses your command the redirections must be done first and since > overwrites the contents your file is clobbered before it is read i.e it's empty!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top