1

I know there are 3 streams attached to a process when it is run namely the input, output and error stream.

And redirection execution work from left to right.

I intend to execute a command, redirect its output stream to a file and its error stream to the same file as well.

-- nofile does not exists, text1 file does exists

head nofile text1 1> output.txt 2> output.txt  -- I know this won't work.

head nofile text1 1> output.txt 2>&1 -- while this will work, passing the error stream to the output ste

q1) Why ?

If it is a matter of "it is suppose to be written this way" then why can't the below work as well

head nofile text1 2>&1 1> output.txt
head nofile text1 2>&1> output.txt

On the above i am redirecting the error stream to output stream, the output stream to the file. Its logic is the same as the above.

  • 2
    I read this 2>&1 as "redirect file descriptor 2 to the thing that fd 1 currently points to" -- this makes it easier to understand why 2>&1 1>file means that stderr does not get redirected to file – glenn jackman Jul 9 '15 at 18:11
  • 1
    There is a nice illustrated tutorial at Illustrated Redirection Tutorial which makes this easier to understand. – DavidPostill Jul 9 '15 at 18:26
0

Answer #1: Race conflict

  • head nofile text1 1> output.txt 2> output.txt # -- I know this won't work.`

This actually works, even if not as you expected and doesn't comply your purpose.
You have 2 file-descriptors that will be redirected independently to the same output file with > output.txt.
One file-descriptor will act faster: it will create the output.txt file and it will start to write inside it.
When the second file-descriptor will start to act, it will recreate the same file (> output.txt), erasing what inside.
You will lose the first part written by the first file-descriptor, if there is any.
Expect a garbled output especially with long outputs. See this answer too.
Consider that the behaviour is not always reproducible. On my system, today, the file is created with the error inside as a first line and the text after.

  • head nofile text1 1> output.txt 2>&1 # ok this works

This works because first you change the redirection for standard output to the file output.txt. Then you ask to redirect the standard error to the same destination of the standard output, that means the file output.txt.

Answer #2: Order matters
The core of the answer: bash redirecting is no commutative it means that orders matter:

head nofile text1 2>&1 1> output.txt
head nofile text1 2>&1> output.txt

Here before you ask to redirect the standard error to the standard output destination (probably the current tty). Then you ask to change only the standard output to the output file output.txt. (both command 1>output.txt and >output.txt act in the same way). The standard error remain redirected where it was before (probably the current tty).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.