Bash – What exactly happens if input and output file is the same

bashio-redirectionshell

Let's say that I execute following command:

tr a-z A-Z < file > file

There are two redirections: < file and > file. Both are processed before tr command and as far as I know, if there are multiple redirections, then they are processed from left to right. In other words first < file and then > file. Does the < file simply mean that if command starts, then stdin comes from file named file? Then the > file part is processed and this means that output is sent to file named file. Also file named file is truncated to zero size. Now finally the commands(tr in my example) starts, but as the input file was truncated to zero in previous step, then it simply processes an empty file?

Best Answer

That's right. > truncates the file before the command is started, so the command sees an empty input file. It doesn't actually matter that the redirections are performed from left to right (except that you'll get an error if the file doesn't exist, whereas >file <file would create the file first).

With somecommand <file >>file, most of the time, you'll get an infinite loop as the command reads its own input. However, for a short file, it's possible that the command detects the end of the input before it's written out anything, in which case this will behave as if the input and output were separate files.

With somecommand <file 1<>file, it's more complicated. Depending on whether the command expands or shrinks the file, it may or may not loop on its own input. If the command always shrinks the file (e.g. grep without things like line numbering or coloring), i.e. if byte N of the output always depends only on bytes 0..N-1 of the input, then this behaves as if the two files were different. I don't recommend relying on that though: it's fragile in many ways, and leaves a mess if the command is interrupted in the middle.

Related Question