Command redirection to multiple files: command >file1 >file2
Solution 1
I think there's a difference between how you think shell redirection works and how it really does.
You cannot redirect the output of the shell multiple times and expect it to be redirected to all the locations you've specified. Instead, it will only be redirected to the last location, which in your case is file2
. The answer by Chaos provides a decent explanation on how such I/O Redirection works.
What you really want to do is:
$ cat example.txt | tee file1 > file2
tee
is a program that reads from the standard input and writes to multiple file descriptors. One of them is always the standard output. So we use tee
to write the output to file1
and then redirect its stdout to file2
.
Also, based on suggestions in the comments, this is a better way to do what you're looking for:
$ tee file1 > file2 < example.txt
This approach has the advantage that it redirects the stdin
instead of trying to read over a pipe. This means that the shell now needs to spawn one less process. It also eliminates what is known as "Useless use of cat".
Solution 2
What you did, is called I/O-Redirection. >file
redirects the standard output (stdout) to the given file
. In you case you did that 2 times. The shell doesn't handle a redirection of the same output multiple times .
In this case:
cat somefile >file1 >file2
The shell processes the redirections before the command (cat somefile
) is executed. That means the >
truncates file to zero length, because you override the files content. The file must be empty before the shell can execute the command. This is done with both >
redirections.
Now, the second one (>file2
) overrides the first one (>file1
), because the shell processes the redirection in order of appearance. So, the last one is the one that will effectvely be used. The output of cat somefile
will therefore be redirected to file2
and file1
will be truncated to zero length.
Redirecting stdout to multiple processes/files can be done with tee
like this:
cat somefile | tee file1 file2 file3 fileX
This will print the contents to stdout and to all files given as paramters.
Solution 3
In zsh
with MULTIOS option set, you can use:
cat somefile >file1 >file2
as in this case, zsh
action similar to tee
.
Related videos on Youtube
Charlie Albert
Updated on September 18, 2022Comments
-
Charlie Albert over 1 year
I have this command:
cat somefile >file1 >file2
After I executed this command I can't figure out why
file1
has nothing in it. It should have the output of the first file (somefile
), but nothing is in it.Can you explain to me why it does not copy or write my output from
somefile
? (file2
contains my output, butfile1
contains nothing)-
vonbrand over 8 yearsA
>
redirects the output to a file, period. Usetee(1)
if you want to duplicate output to a file and send it on. -
Alexis Wilke over 4 yearsIn sh and bash (and probably others) you can open multiple output files like so:
cat somefile >file1 3>file2 4>file3
. This means you start the program with two extra files opened as fileno 3 and fileno 4. Of course,cat
will ignore those, but it can be useful if you want to have different log files, for example, or you're somehow splitting the input in 3 parts, etc.
-
-
roaima over 8 yearsBetter,
tee file1 >file2 <example.txt
-
The Sidhekin over 8 yearsOh, it handles redirection of the same output multiple times. It's just doesn't handle it the way the OP expected it to. ;-) (You actually describe well how it's handled.)
-
user2357112 over 8 yearsIt might be better to do something like
tee <somefile >file1 file2
, sincecat somefile | tee file1 file2 file3 fileX
dumps the contents ofsomefile
to your terminal and doesn't really need thecat
call. -
Brandin over 8 yearsI much prefer the
cat ... | tee
approach. Maybe the cat is useless, but it is much easier for me to follow. Is your system really so constrained that firing off an extracat
process is going to be an issue?? -
darnir over 8 yearsI agree that the
cat ... | tee
approach is cleaner. Also, a system is barely ever so constrained that it cannot handle the extra call tocat
. It's however another option. -
Nate Eldredge over 8 years@roaima: I presume the
cat
is not really a UUOC but a placeholder for some more complicated command. (Anybody who actually wanted to copy the contents of a file to two other files would just usecp
twice.) Omitting it obscures the general principle being used. -
Alexis Wilke over 4 yearsNote that
zsh
can be used with multiple>file{1,2,3}
and it works as if you usedtee
.