Redirecting input and output to the same file

How can I redirect input and output to the same file at all? I mean sort

there is a command for a command and there -o

may be other such parameters for that command. But how can I even redirect input and output to the same file without crashing the file?

For example: sort a.txt > a.txt

destroys the contents of the file a.txt, but I want to keep the response in the same file. I know I can use mv

it rm

after using the temp file too, but can this be done directly?

+3


source to share


3 answers


If you are familiar with POSIX apis, you will realize that opening a file has several possible modes, but the most common ones are read, written, and appended. You will remember that if you open the file for writing, you trim it immediately.

Forwarding is directly similar to that used in general modes.

 > x # open x for writing
 < x # open x for reading
>> x # open x for appending

      



There is no shell redirection, which are unfortunately equivalent to modes like O_RDWR

.

You can check this with a parameter noclobber

, but you cannot open the file for reading and writing using the shell redirection operators. You must use a temporary file.

+2


source


As mentioned in BashPitfalls entry # 13 , you can use sponge

from moreutils

to "soak" data before opening a file to write to it.

Usage example: sort a.txt | sponge a.txt

While the BashPitfalls page mentions that there might be data loss, the sponge man page says



It also creates the output file atomically by renaming the temporary file to the location [...]

This would make it more dangerous than writing to a temporary file and executing mv

.

Credit to Charles Duffy for pointing out the BashPitfalls entry in the comments.

+1


source


Not if the command does not support execution itself mv

after it completes.

The environment truncates the output file before it even executes the command you told it to execute. (Try with a command that doesn't exist and you'll see it still gets truncated.)

This is why some commands have options for doing this (in order to save you the trouble of using command input > output && mv output input

or the like).

0


source







All Articles