Is this a typo in Bash manual's redirection section?How does redirecting stdout to stderr workwhat is...

Charges from Dollar General have never shown up on my debit card. How can I resolve this?

What is Ferb's name short for?

Problem with NSolve with Logarithm

What happens when supercritical fuel tanks deplete below critical point?

Did I Traumatize My Puppy?

Encountering former, abusive advisor at a conference

On notice period - coworker I need to train is giving me the silent treatment

Digit Date Range

How to find the sum of digits of a number whose prime factorisation is given

Is it possible for a country to develop the equivalent of a Second Industrial Revolution while under a war of attrition?

Labeling lines that are not within polygons using field calculator

Sum of all digits in a string

Replace spaces with comma but not in the whole line

I run daily 5kms but I cant seem to improve stamina when playing soccer

Is it allowed to let the engine of an aircraft idle without a pilot in the plane. (For both helicopters and aeroplanes)

How were Kurds involved (or not) in the invasion of Normandy?

Car as a good investment

Why do military jets sometimes have elevators in a depressed position when parked?

How to deal with people whose priority is to not get blamed?

Did the US push the Kurds to lower their defences against Turkey in the months preceding the latest Turkish military operation against them?

Why is my paper "under review" if it contains no results?

Did Terry Pratchett ever explain the inspiration behind the Luggage?

If you revoke a certificate authority's certificate, do all of the certificates it issued become invalid as well?

How to figure out key from key signature?



Is this a typo in Bash manual's redirection section?


How does redirecting stdout to stderr workwhat is >> symbol and >& in unix/Linux?How to grep standard error stream (stderr)?Restoring output to the terminal after having issued “exec &>filename”Caveats with Stdout/Stderr Redirection to Files?Do not wait until the return for Shell redirectionSeparate dd data from output through netcat to parse outputAppend string on redirectProcess substitution and redirection using tee






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{
margin-bottom:0;
}








13

















Note that the order of redirections is significant.  For example, the command

ls > dirlist 2>&1

directs both standard output and standard error to the file dirlist,
while the command

ls 2>&1 > dirlist

directs only the standard output to file dirlist, because the
standard error was duplicated from the standard output before the standard
output was redirected to dirlist.


Now, that last part is confusing to me. In that case, any standard error would be printed to the terminal and any STDOUT would go to the dirlist file. That is what would happen, but that is not how I understand the manual.



It seems like it should say "because the standard error was duplicated from the standard output AFTER the standard output was redirected to dirlist". If STDERR was sent to STDOUT before STDOUT was directed to a file, then wouldn't the file contain STDOUT AND STDERR?



Can someone please clear this up for me? Is it just poor reading comprehension on my part? The use of the word duplication seems a little strange to me in this context. Perhaps that is throwing me.










share|improve this question





























  • See stackoverflow.com/q/14615653/1030675

    – choroba
    Jul 24 '13 at 15:48






  • 1





    A classic case of mixing up operations that are "by value" vs "by reference". When you duplicate a file descriptor it is a by value operation. In programming, after a = 1; b = a; a = 2 you expect a == 2 && b == 1 to be true. The redirection 2>&1 is similar to the b = a assignment - it is by value, not by reference. 2>&1 does not wed file descriptor 2 to file descriptor 1 for all of eternity - they are still 2 distinct file descriptors, who happen to point to the same file.

    – jw013
    Jul 30 '13 at 20:15




















13

















Note that the order of redirections is significant.  For example, the command

ls > dirlist 2>&1

directs both standard output and standard error to the file dirlist,
while the command

ls 2>&1 > dirlist

directs only the standard output to file dirlist, because the
standard error was duplicated from the standard output before the standard
output was redirected to dirlist.


Now, that last part is confusing to me. In that case, any standard error would be printed to the terminal and any STDOUT would go to the dirlist file. That is what would happen, but that is not how I understand the manual.



It seems like it should say "because the standard error was duplicated from the standard output AFTER the standard output was redirected to dirlist". If STDERR was sent to STDOUT before STDOUT was directed to a file, then wouldn't the file contain STDOUT AND STDERR?



Can someone please clear this up for me? Is it just poor reading comprehension on my part? The use of the word duplication seems a little strange to me in this context. Perhaps that is throwing me.










share|improve this question





























  • See stackoverflow.com/q/14615653/1030675

    – choroba
    Jul 24 '13 at 15:48






  • 1





    A classic case of mixing up operations that are "by value" vs "by reference". When you duplicate a file descriptor it is a by value operation. In programming, after a = 1; b = a; a = 2 you expect a == 2 && b == 1 to be true. The redirection 2>&1 is similar to the b = a assignment - it is by value, not by reference. 2>&1 does not wed file descriptor 2 to file descriptor 1 for all of eternity - they are still 2 distinct file descriptors, who happen to point to the same file.

    – jw013
    Jul 30 '13 at 20:15
















13












13








13


5






Note that the order of redirections is significant.  For example, the command

ls > dirlist 2>&1

directs both standard output and standard error to the file dirlist,
while the command

ls 2>&1 > dirlist

directs only the standard output to file dirlist, because the
standard error was duplicated from the standard output before the standard
output was redirected to dirlist.


Now, that last part is confusing to me. In that case, any standard error would be printed to the terminal and any STDOUT would go to the dirlist file. That is what would happen, but that is not how I understand the manual.



It seems like it should say "because the standard error was duplicated from the standard output AFTER the standard output was redirected to dirlist". If STDERR was sent to STDOUT before STDOUT was directed to a file, then wouldn't the file contain STDOUT AND STDERR?



Can someone please clear this up for me? Is it just poor reading comprehension on my part? The use of the word duplication seems a little strange to me in this context. Perhaps that is throwing me.










share|improve this question

















Note that the order of redirections is significant.  For example, the command

ls > dirlist 2>&1

directs both standard output and standard error to the file dirlist,
while the command

ls 2>&1 > dirlist

directs only the standard output to file dirlist, because the
standard error was duplicated from the standard output before the standard
output was redirected to dirlist.


Now, that last part is confusing to me. In that case, any standard error would be printed to the terminal and any STDOUT would go to the dirlist file. That is what would happen, but that is not how I understand the manual.



It seems like it should say "because the standard error was duplicated from the standard output AFTER the standard output was redirected to dirlist". If STDERR was sent to STDOUT before STDOUT was directed to a file, then wouldn't the file contain STDOUT AND STDERR?



Can someone please clear this up for me? Is it just poor reading comprehension on my part? The use of the word duplication seems a little strange to me in this context. Perhaps that is throwing me.







bash shell io-redirection






share|improve this question
















share|improve this question













share|improve this question




share|improve this question








edited Jul 24 '13 at 22:26









Gilles

579k141 gold badges1195 silver badges1708 bronze badges




579k141 gold badges1195 silver badges1708 bronze badges










asked Jul 24 '13 at 15:40









Gregg LeventhalGregg Leventhal

3,21113 gold badges48 silver badges81 bronze badges




3,21113 gold badges48 silver badges81 bronze badges
















  • See stackoverflow.com/q/14615653/1030675

    – choroba
    Jul 24 '13 at 15:48






  • 1





    A classic case of mixing up operations that are "by value" vs "by reference". When you duplicate a file descriptor it is a by value operation. In programming, after a = 1; b = a; a = 2 you expect a == 2 && b == 1 to be true. The redirection 2>&1 is similar to the b = a assignment - it is by value, not by reference. 2>&1 does not wed file descriptor 2 to file descriptor 1 for all of eternity - they are still 2 distinct file descriptors, who happen to point to the same file.

    – jw013
    Jul 30 '13 at 20:15





















  • See stackoverflow.com/q/14615653/1030675

    – choroba
    Jul 24 '13 at 15:48






  • 1





    A classic case of mixing up operations that are "by value" vs "by reference". When you duplicate a file descriptor it is a by value operation. In programming, after a = 1; b = a; a = 2 you expect a == 2 && b == 1 to be true. The redirection 2>&1 is similar to the b = a assignment - it is by value, not by reference. 2>&1 does not wed file descriptor 2 to file descriptor 1 for all of eternity - they are still 2 distinct file descriptors, who happen to point to the same file.

    – jw013
    Jul 30 '13 at 20:15



















See stackoverflow.com/q/14615653/1030675

– choroba
Jul 24 '13 at 15:48





See stackoverflow.com/q/14615653/1030675

– choroba
Jul 24 '13 at 15:48




1




1





A classic case of mixing up operations that are "by value" vs "by reference". When you duplicate a file descriptor it is a by value operation. In programming, after a = 1; b = a; a = 2 you expect a == 2 && b == 1 to be true. The redirection 2>&1 is similar to the b = a assignment - it is by value, not by reference. 2>&1 does not wed file descriptor 2 to file descriptor 1 for all of eternity - they are still 2 distinct file descriptors, who happen to point to the same file.

– jw013
Jul 30 '13 at 20:15







A classic case of mixing up operations that are "by value" vs "by reference". When you duplicate a file descriptor it is a by value operation. In programming, after a = 1; b = a; a = 2 you expect a == 2 && b == 1 to be true. The redirection 2>&1 is similar to the b = a assignment - it is by value, not by reference. 2>&1 does not wed file descriptor 2 to file descriptor 1 for all of eternity - they are still 2 distinct file descriptors, who happen to point to the same file.

– jw013
Jul 30 '13 at 20:15












4 Answers
4






active

oldest

votes


















23


















Duplication is really the important part here.



Let's see where the file descriptors are going to before redirection. This is normally the current terminal, e.g.:



STDOUT ---> /dev/pts/1
STDERR ---> /dev/pts/1


Now, if we call ls -l without redirection, output and error messages go to my terminal under /dev/pts/1.



If we first redirect the STDOUT to a file (ls -l > dirlist), it looks like this:



STDOUT ---> /home/bon/dirlist
STDERR ---> /dev/pts/1


When we then redirect STDERR to a duplicate of STDOUT's file descriptor (ls -l > dirlist 2>&1), STDERR goes to a duplicate of /home/bon/dirlist:



STDOUT ---> /home/bon/dirlist
STDERR ---> /home/bon/dirlist


If we would first redirect STDERR to a duplicate of STDOUT's file descriptor (ls -l 2>&1):



STDOUT ---> /dev/pts/1
STDERR ---> /dev/pts/1


and then STDOUT to a file (ls -l 2>&1 > dirlist), we would get this:



STDOUT ---> /home/bon/dirlist
STDERR ---> /dev/pts/1


Here, STDERR is still going to the terminal.



You see, the order in the man page is correct.





Testing Redirection



Now, you can test that yourself. Using ls -l /proc/$$/fd/, you see where STDOUT (with fd 1) and STDERR (with fd 2), are going for the current process:



$ ls -l /proc/$$/fd/
total 0
lrwx------ 1 bon bon 64 Jul 24 18:19 0 -> /dev/pts/1
lrwx------ 1 bon bon 64 Jul 24 18:19 1 -> /dev/pts/1
lrwx------ 1 bon bon 64 Jul 24 07:41 2 -> /dev/pts/1
lrwx------ 1 bon bon 64 Jul 24 18:19 255 -> /dev/pts/1


Let's create a small shell script that shows where your file descriptors are pointed. This way, we always get the state when calling ls, including any redirection from the calling shell.



$ cat > lookfd.sh
#!/bin/sh
ls -l /proc/$$/fd/
^D
$ chmod +x lookfd.sh


(With CtrlD, you send an end-of-file and so stop the cat command reading from STDIN.)



Now, call this script with varying combinations of redirection:



$ ./lookfd.sh 
total 0
lrwx------ 1 bon bon 64 Jul 24 19:08 0 -> /dev/pts/1
lrwx------ 1 bon bon 64 Jul 24 19:08 1 -> /dev/pts/1
lrwx------ 1 bon bon 64 Jul 24 19:08 2 -> /dev/pts/1
lr-x------ 1 bon bon 64 Jul 24 19:08 255 -> /home/bon/lookfd.sh
$ ./lookfd.sh > foo.out
$ cat foo.out
total 0
lrwx------ 1 bon bon 64 Jul 24 19:10 0 -> /dev/pts/1
l-wx------ 1 bon bon 64 Jul 24 19:10 1 -> /home/bon/foo.out
lrwx------ 1 bon bon 64 Jul 24 19:10 2 -> /dev/pts/1
lr-x------ 1 bon bon 64 Jul 24 19:10 255 -> /home/bon/lookfd.sh
$ ./lookfd.sh 2>&1 > foo.out
$ cat foo.out
total 0
lrwx------ 1 bon bon 64 Jul 24 19:10 0 -> /dev/pts/1
l-wx------ 1 bon bon 64 Jul 24 19:10 1 -> /home/bon/foo.out
lrwx------ 1 bon bon 64 Jul 24 19:10 2 -> /dev/pts/1
lr-x------ 1 bon bon 64 Jul 24 19:10 255 -> /home/bon/lookfd.sh
$ ./lookfd.sh > foo.out 2>&1
$ cat foo.out
total 0
lrwx------ 1 bon bon 64 Jul 24 19:11 0 -> /dev/pts/1
l-wx------ 1 bon bon 64 Jul 24 19:11 1 -> /home/bon/foo.out
l-wx------ 1 bon bon 64 Jul 24 19:11 2 -> /home/bon/foo.out
lr-x------ 1 bon bon 64 Jul 24 19:11 255 -> /home/bon/lookfd.sh


You can see, that the file descriptors 1 (for STDOUT) and 2 (for STDERR) vary. For fun, you could also redirect STDIN and see the result:



$ ./lookfd.sh < /dev/zero
total 0
lr-x------ 1 bon bon 64 Jul 24 19:18 0 -> /dev/zero
lrwx------ 1 bon bon 64 Jul 24 19:18 1 -> /dev/pts/1
lrwx------ 1 bon bon 64 Jul 24 19:18 2 -> /dev/pts/1
lr-x------ 1 bon bon 64 Jul 24 19:18 255 -> /home/bon/lookfd.sh


(Question left to the reader: Where does file descriptor 255 point? ;-))






share|improve this answer





























  • +1 - excellent answer. Extremely well written and terrific examples. Thank you!!!

    – slm
    Jul 24 '13 at 18:50











  • I see, I think my misunderstanding was that the redirection would be persistent for all following commands, so that any STDERR for the rest of the line would go to STDOUT.

    – Gregg Leventhal
    Jul 31 '13 at 13:56



















2


















No, the manual is right.



If at first 1 points to the terminal, and 2 also to the terminal, then:



command  2>&1   1>somewhere


redirection evaluatino will happen from left to right.



So it will FIRST evaluate 2>&1, and thus FIRST copy what fd 1 used to point to (ie, the file descriptor of the terminal, usually /dev/tty) into fd 2.



So at that point fd 2 now points to where fd 1 used to point to (the terminal)



And THEN it evaluates the 1>somewhere part, and thus will copy the file descriptor of somewhere in fd 1 (so at that point, fd 1 now points to somewhere, and fd 2 still points to the terminal)



So it does indeed print 1 into "somewhere" and 2 into the terminal, as 2 was duplicated from 1 BEFORE 1 has been changed.



The other order:



command  1>somewhere 2>&1


will first redirect fd 1 to somewhere, and then copy that same reference into fd 2, so at the end 2 also points to somewhere.
But they are not "linked" from now on. Each can still be redirected separately.



ex:



command  1>somewhere 2>&1
exec 2>/dev/null


At the end of that one, fd 1 points to somewhere, and fd 2 is directed to /dev/null



Usual names for fd 1 is STDOUT (standard output), and usual name for fd 2 is STDERR (standard error, as it's commonly used to display errors without interfering with STDOUT)






share|improve this answer





























  • @Michael-mrozek : thanks for the edit, but I insist on saying "copy" instead of "duplicate" as "duplicate" could lead one to believe that from now on both are "the same thing", which is not true. ex: cmd 1>somewhere 2>&1 ; exec 2>/dev/null : after the exec, only 2 has been redirected to /dev/null (1 is still going to "somewhere"). I do need help to come up with a way to say "what 1 points to" instead of "the fd 1", however... as that is also confusing...

    – Olivier Dulac
    Jul 24 '13 at 17:19








  • 1





    I'm not sure what you mean; you're the one who changed it from "copy" to "duplicate". All I did was capitalize and format things, I didn't change a word

    – Michael Mrozek
    Jul 24 '13 at 17:23











  • doh... ^^ sorry. And I edited again to reformulate to make more precise what is copied into what ^^

    – Olivier Dulac
    Jul 24 '13 at 17:26



















1


















I think the confusing part here is the misapprehension that redirecting stderr to stdout actually connects the two streams.



A perfectly reasonable idea but what happens when you write 2>&1 is stderr takes a peekaboo at what stdout is writing to and writes to the same place itself. Therefore if you subsequently tell stdout to go write somewhere else it has no effect on the destination of stderr which has already been moved.



I think it's a tad counterintuitive myself but that's how it works. Set up where you want to write to first then tell everyone "copy me".
Hope that clarifies...






share|improve this answer




































    0


















    DUPLICATION...



    is important, but rather in the sense that it is the source of much confusion. It is really quite simple. This answer is just a "radical" illustration.



    The accepted answer is good, but too long and it emphasizes "duplicatition".



    The Q wisely ends with:




    The use of the word duplication seems a little strange to me in
    this context. Perhaps that is throwing me.




    I use bash notation and define variables "one" and "two" as filehandles "1" and "2". The (output) redirection operator > is an assignment =. & and $ mean "value" of.



    The man bash examples (with default "1" added)



    ls 1>dirlist 2>&1      # both to dirlist
    ls 2>&1 1>dirlist # 1 to dirlist, 2 stays on tty/screen


    become:



    one=dirlist  two=$one


    and



    two=$one   one=dirlist


    And even this is non-automatic to me, and some others I guess. The first line leaves you with $one and $two both containing "dirlist". Of course.



    The second line starts with a useless assignment. Both start by definition with "TTY" (a bit symbolic) as their direction; no value is changed by this assignment, and with variables as with filehandles, nothing is magically linked. Variable two is not affected by the following one=dirlist. Of course not.



    Sombody here (6 years ago) suggested "point to" instead of "copy" or "duplicate", and then realized: that would be confusing too.



    This duplication or pointer semantic is not even needed. Maybe it's the ampersand that needs more attention. The "value of" operator/token/whatever.



    If - and only if - you are looking for a way to get a surprising job number on your console, then a "done" message plus as a bonus a file named "2", then you go:



    ls 1>2& 2>/dev/null


    It reads naturally as "copy"/"duplicate" 1 to 2, and then both together to null. But the idea is wrong, and also the syntax. (but no syntax error, it is valid)



    The right way to plan it is to redirect any of the two to null, and then redirect the OTHER to the SAME place:



    ls 1>/dev/null 2>&1
    # or
    ls 2>/dev/null 1>&2


    (the leading "1" can be left away)



    (OK the acc. A is not too long, but is too much of a list - or: very good visualisation, not so good explanation)






    share|improve this answer




























      Your Answer








      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "106"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: false,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: null,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/4.0/"u003ecc by-sa 4.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });















      draft saved

      draft discarded
















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f84279%2fis-this-a-typo-in-bash-manuals-redirection-section%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown


























      4 Answers
      4






      active

      oldest

      votes








      4 Answers
      4






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      23


















      Duplication is really the important part here.



      Let's see where the file descriptors are going to before redirection. This is normally the current terminal, e.g.:



      STDOUT ---> /dev/pts/1
      STDERR ---> /dev/pts/1


      Now, if we call ls -l without redirection, output and error messages go to my terminal under /dev/pts/1.



      If we first redirect the STDOUT to a file (ls -l > dirlist), it looks like this:



      STDOUT ---> /home/bon/dirlist
      STDERR ---> /dev/pts/1


      When we then redirect STDERR to a duplicate of STDOUT's file descriptor (ls -l > dirlist 2>&1), STDERR goes to a duplicate of /home/bon/dirlist:



      STDOUT ---> /home/bon/dirlist
      STDERR ---> /home/bon/dirlist


      If we would first redirect STDERR to a duplicate of STDOUT's file descriptor (ls -l 2>&1):



      STDOUT ---> /dev/pts/1
      STDERR ---> /dev/pts/1


      and then STDOUT to a file (ls -l 2>&1 > dirlist), we would get this:



      STDOUT ---> /home/bon/dirlist
      STDERR ---> /dev/pts/1


      Here, STDERR is still going to the terminal.



      You see, the order in the man page is correct.





      Testing Redirection



      Now, you can test that yourself. Using ls -l /proc/$$/fd/, you see where STDOUT (with fd 1) and STDERR (with fd 2), are going for the current process:



      $ ls -l /proc/$$/fd/
      total 0
      lrwx------ 1 bon bon 64 Jul 24 18:19 0 -> /dev/pts/1
      lrwx------ 1 bon bon 64 Jul 24 18:19 1 -> /dev/pts/1
      lrwx------ 1 bon bon 64 Jul 24 07:41 2 -> /dev/pts/1
      lrwx------ 1 bon bon 64 Jul 24 18:19 255 -> /dev/pts/1


      Let's create a small shell script that shows where your file descriptors are pointed. This way, we always get the state when calling ls, including any redirection from the calling shell.



      $ cat > lookfd.sh
      #!/bin/sh
      ls -l /proc/$$/fd/
      ^D
      $ chmod +x lookfd.sh


      (With CtrlD, you send an end-of-file and so stop the cat command reading from STDIN.)



      Now, call this script with varying combinations of redirection:



      $ ./lookfd.sh 
      total 0
      lrwx------ 1 bon bon 64 Jul 24 19:08 0 -> /dev/pts/1
      lrwx------ 1 bon bon 64 Jul 24 19:08 1 -> /dev/pts/1
      lrwx------ 1 bon bon 64 Jul 24 19:08 2 -> /dev/pts/1
      lr-x------ 1 bon bon 64 Jul 24 19:08 255 -> /home/bon/lookfd.sh
      $ ./lookfd.sh > foo.out
      $ cat foo.out
      total 0
      lrwx------ 1 bon bon 64 Jul 24 19:10 0 -> /dev/pts/1
      l-wx------ 1 bon bon 64 Jul 24 19:10 1 -> /home/bon/foo.out
      lrwx------ 1 bon bon 64 Jul 24 19:10 2 -> /dev/pts/1
      lr-x------ 1 bon bon 64 Jul 24 19:10 255 -> /home/bon/lookfd.sh
      $ ./lookfd.sh 2>&1 > foo.out
      $ cat foo.out
      total 0
      lrwx------ 1 bon bon 64 Jul 24 19:10 0 -> /dev/pts/1
      l-wx------ 1 bon bon 64 Jul 24 19:10 1 -> /home/bon/foo.out
      lrwx------ 1 bon bon 64 Jul 24 19:10 2 -> /dev/pts/1
      lr-x------ 1 bon bon 64 Jul 24 19:10 255 -> /home/bon/lookfd.sh
      $ ./lookfd.sh > foo.out 2>&1
      $ cat foo.out
      total 0
      lrwx------ 1 bon bon 64 Jul 24 19:11 0 -> /dev/pts/1
      l-wx------ 1 bon bon 64 Jul 24 19:11 1 -> /home/bon/foo.out
      l-wx------ 1 bon bon 64 Jul 24 19:11 2 -> /home/bon/foo.out
      lr-x------ 1 bon bon 64 Jul 24 19:11 255 -> /home/bon/lookfd.sh


      You can see, that the file descriptors 1 (for STDOUT) and 2 (for STDERR) vary. For fun, you could also redirect STDIN and see the result:



      $ ./lookfd.sh < /dev/zero
      total 0
      lr-x------ 1 bon bon 64 Jul 24 19:18 0 -> /dev/zero
      lrwx------ 1 bon bon 64 Jul 24 19:18 1 -> /dev/pts/1
      lrwx------ 1 bon bon 64 Jul 24 19:18 2 -> /dev/pts/1
      lr-x------ 1 bon bon 64 Jul 24 19:18 255 -> /home/bon/lookfd.sh


      (Question left to the reader: Where does file descriptor 255 point? ;-))






      share|improve this answer





























      • +1 - excellent answer. Extremely well written and terrific examples. Thank you!!!

        – slm
        Jul 24 '13 at 18:50











      • I see, I think my misunderstanding was that the redirection would be persistent for all following commands, so that any STDERR for the rest of the line would go to STDOUT.

        – Gregg Leventhal
        Jul 31 '13 at 13:56
















      23


















      Duplication is really the important part here.



      Let's see where the file descriptors are going to before redirection. This is normally the current terminal, e.g.:



      STDOUT ---> /dev/pts/1
      STDERR ---> /dev/pts/1


      Now, if we call ls -l without redirection, output and error messages go to my terminal under /dev/pts/1.



      If we first redirect the STDOUT to a file (ls -l > dirlist), it looks like this:



      STDOUT ---> /home/bon/dirlist
      STDERR ---> /dev/pts/1


      When we then redirect STDERR to a duplicate of STDOUT's file descriptor (ls -l > dirlist 2>&1), STDERR goes to a duplicate of /home/bon/dirlist:



      STDOUT ---> /home/bon/dirlist
      STDERR ---> /home/bon/dirlist


      If we would first redirect STDERR to a duplicate of STDOUT's file descriptor (ls -l 2>&1):



      STDOUT ---> /dev/pts/1
      STDERR ---> /dev/pts/1


      and then STDOUT to a file (ls -l 2>&1 > dirlist), we would get this:



      STDOUT ---> /home/bon/dirlist
      STDERR ---> /dev/pts/1


      Here, STDERR is still going to the terminal.



      You see, the order in the man page is correct.





      Testing Redirection



      Now, you can test that yourself. Using ls -l /proc/$$/fd/, you see where STDOUT (with fd 1) and STDERR (with fd 2), are going for the current process:



      $ ls -l /proc/$$/fd/
      total 0
      lrwx------ 1 bon bon 64 Jul 24 18:19 0 -> /dev/pts/1
      lrwx------ 1 bon bon 64 Jul 24 18:19 1 -> /dev/pts/1
      lrwx------ 1 bon bon 64 Jul 24 07:41 2 -> /dev/pts/1
      lrwx------ 1 bon bon 64 Jul 24 18:19 255 -> /dev/pts/1


      Let's create a small shell script that shows where your file descriptors are pointed. This way, we always get the state when calling ls, including any redirection from the calling shell.



      $ cat > lookfd.sh
      #!/bin/sh
      ls -l /proc/$$/fd/
      ^D
      $ chmod +x lookfd.sh


      (With CtrlD, you send an end-of-file and so stop the cat command reading from STDIN.)



      Now, call this script with varying combinations of redirection:



      $ ./lookfd.sh 
      total 0
      lrwx------ 1 bon bon 64 Jul 24 19:08 0 -> /dev/pts/1
      lrwx------ 1 bon bon 64 Jul 24 19:08 1 -> /dev/pts/1
      lrwx------ 1 bon bon 64 Jul 24 19:08 2 -> /dev/pts/1
      lr-x------ 1 bon bon 64 Jul 24 19:08 255 -> /home/bon/lookfd.sh
      $ ./lookfd.sh > foo.out
      $ cat foo.out
      total 0
      lrwx------ 1 bon bon 64 Jul 24 19:10 0 -> /dev/pts/1
      l-wx------ 1 bon bon 64 Jul 24 19:10 1 -> /home/bon/foo.out
      lrwx------ 1 bon bon 64 Jul 24 19:10 2 -> /dev/pts/1
      lr-x------ 1 bon bon 64 Jul 24 19:10 255 -> /home/bon/lookfd.sh
      $ ./lookfd.sh 2>&1 > foo.out
      $ cat foo.out
      total 0
      lrwx------ 1 bon bon 64 Jul 24 19:10 0 -> /dev/pts/1
      l-wx------ 1 bon bon 64 Jul 24 19:10 1 -> /home/bon/foo.out
      lrwx------ 1 bon bon 64 Jul 24 19:10 2 -> /dev/pts/1
      lr-x------ 1 bon bon 64 Jul 24 19:10 255 -> /home/bon/lookfd.sh
      $ ./lookfd.sh > foo.out 2>&1
      $ cat foo.out
      total 0
      lrwx------ 1 bon bon 64 Jul 24 19:11 0 -> /dev/pts/1
      l-wx------ 1 bon bon 64 Jul 24 19:11 1 -> /home/bon/foo.out
      l-wx------ 1 bon bon 64 Jul 24 19:11 2 -> /home/bon/foo.out
      lr-x------ 1 bon bon 64 Jul 24 19:11 255 -> /home/bon/lookfd.sh


      You can see, that the file descriptors 1 (for STDOUT) and 2 (for STDERR) vary. For fun, you could also redirect STDIN and see the result:



      $ ./lookfd.sh < /dev/zero
      total 0
      lr-x------ 1 bon bon 64 Jul 24 19:18 0 -> /dev/zero
      lrwx------ 1 bon bon 64 Jul 24 19:18 1 -> /dev/pts/1
      lrwx------ 1 bon bon 64 Jul 24 19:18 2 -> /dev/pts/1
      lr-x------ 1 bon bon 64 Jul 24 19:18 255 -> /home/bon/lookfd.sh


      (Question left to the reader: Where does file descriptor 255 point? ;-))






      share|improve this answer





























      • +1 - excellent answer. Extremely well written and terrific examples. Thank you!!!

        – slm
        Jul 24 '13 at 18:50











      • I see, I think my misunderstanding was that the redirection would be persistent for all following commands, so that any STDERR for the rest of the line would go to STDOUT.

        – Gregg Leventhal
        Jul 31 '13 at 13:56














      23














      23










      23









      Duplication is really the important part here.



      Let's see where the file descriptors are going to before redirection. This is normally the current terminal, e.g.:



      STDOUT ---> /dev/pts/1
      STDERR ---> /dev/pts/1


      Now, if we call ls -l without redirection, output and error messages go to my terminal under /dev/pts/1.



      If we first redirect the STDOUT to a file (ls -l > dirlist), it looks like this:



      STDOUT ---> /home/bon/dirlist
      STDERR ---> /dev/pts/1


      When we then redirect STDERR to a duplicate of STDOUT's file descriptor (ls -l > dirlist 2>&1), STDERR goes to a duplicate of /home/bon/dirlist:



      STDOUT ---> /home/bon/dirlist
      STDERR ---> /home/bon/dirlist


      If we would first redirect STDERR to a duplicate of STDOUT's file descriptor (ls -l 2>&1):



      STDOUT ---> /dev/pts/1
      STDERR ---> /dev/pts/1


      and then STDOUT to a file (ls -l 2>&1 > dirlist), we would get this:



      STDOUT ---> /home/bon/dirlist
      STDERR ---> /dev/pts/1


      Here, STDERR is still going to the terminal.



      You see, the order in the man page is correct.





      Testing Redirection



      Now, you can test that yourself. Using ls -l /proc/$$/fd/, you see where STDOUT (with fd 1) and STDERR (with fd 2), are going for the current process:



      $ ls -l /proc/$$/fd/
      total 0
      lrwx------ 1 bon bon 64 Jul 24 18:19 0 -> /dev/pts/1
      lrwx------ 1 bon bon 64 Jul 24 18:19 1 -> /dev/pts/1
      lrwx------ 1 bon bon 64 Jul 24 07:41 2 -> /dev/pts/1
      lrwx------ 1 bon bon 64 Jul 24 18:19 255 -> /dev/pts/1


      Let's create a small shell script that shows where your file descriptors are pointed. This way, we always get the state when calling ls, including any redirection from the calling shell.



      $ cat > lookfd.sh
      #!/bin/sh
      ls -l /proc/$$/fd/
      ^D
      $ chmod +x lookfd.sh


      (With CtrlD, you send an end-of-file and so stop the cat command reading from STDIN.)



      Now, call this script with varying combinations of redirection:



      $ ./lookfd.sh 
      total 0
      lrwx------ 1 bon bon 64 Jul 24 19:08 0 -> /dev/pts/1
      lrwx------ 1 bon bon 64 Jul 24 19:08 1 -> /dev/pts/1
      lrwx------ 1 bon bon 64 Jul 24 19:08 2 -> /dev/pts/1
      lr-x------ 1 bon bon 64 Jul 24 19:08 255 -> /home/bon/lookfd.sh
      $ ./lookfd.sh > foo.out
      $ cat foo.out
      total 0
      lrwx------ 1 bon bon 64 Jul 24 19:10 0 -> /dev/pts/1
      l-wx------ 1 bon bon 64 Jul 24 19:10 1 -> /home/bon/foo.out
      lrwx------ 1 bon bon 64 Jul 24 19:10 2 -> /dev/pts/1
      lr-x------ 1 bon bon 64 Jul 24 19:10 255 -> /home/bon/lookfd.sh
      $ ./lookfd.sh 2>&1 > foo.out
      $ cat foo.out
      total 0
      lrwx------ 1 bon bon 64 Jul 24 19:10 0 -> /dev/pts/1
      l-wx------ 1 bon bon 64 Jul 24 19:10 1 -> /home/bon/foo.out
      lrwx------ 1 bon bon 64 Jul 24 19:10 2 -> /dev/pts/1
      lr-x------ 1 bon bon 64 Jul 24 19:10 255 -> /home/bon/lookfd.sh
      $ ./lookfd.sh > foo.out 2>&1
      $ cat foo.out
      total 0
      lrwx------ 1 bon bon 64 Jul 24 19:11 0 -> /dev/pts/1
      l-wx------ 1 bon bon 64 Jul 24 19:11 1 -> /home/bon/foo.out
      l-wx------ 1 bon bon 64 Jul 24 19:11 2 -> /home/bon/foo.out
      lr-x------ 1 bon bon 64 Jul 24 19:11 255 -> /home/bon/lookfd.sh


      You can see, that the file descriptors 1 (for STDOUT) and 2 (for STDERR) vary. For fun, you could also redirect STDIN and see the result:



      $ ./lookfd.sh < /dev/zero
      total 0
      lr-x------ 1 bon bon 64 Jul 24 19:18 0 -> /dev/zero
      lrwx------ 1 bon bon 64 Jul 24 19:18 1 -> /dev/pts/1
      lrwx------ 1 bon bon 64 Jul 24 19:18 2 -> /dev/pts/1
      lr-x------ 1 bon bon 64 Jul 24 19:18 255 -> /home/bon/lookfd.sh


      (Question left to the reader: Where does file descriptor 255 point? ;-))






      share|improve this answer
















      Duplication is really the important part here.



      Let's see where the file descriptors are going to before redirection. This is normally the current terminal, e.g.:



      STDOUT ---> /dev/pts/1
      STDERR ---> /dev/pts/1


      Now, if we call ls -l without redirection, output and error messages go to my terminal under /dev/pts/1.



      If we first redirect the STDOUT to a file (ls -l > dirlist), it looks like this:



      STDOUT ---> /home/bon/dirlist
      STDERR ---> /dev/pts/1


      When we then redirect STDERR to a duplicate of STDOUT's file descriptor (ls -l > dirlist 2>&1), STDERR goes to a duplicate of /home/bon/dirlist:



      STDOUT ---> /home/bon/dirlist
      STDERR ---> /home/bon/dirlist


      If we would first redirect STDERR to a duplicate of STDOUT's file descriptor (ls -l 2>&1):



      STDOUT ---> /dev/pts/1
      STDERR ---> /dev/pts/1


      and then STDOUT to a file (ls -l 2>&1 > dirlist), we would get this:



      STDOUT ---> /home/bon/dirlist
      STDERR ---> /dev/pts/1


      Here, STDERR is still going to the terminal.



      You see, the order in the man page is correct.





      Testing Redirection



      Now, you can test that yourself. Using ls -l /proc/$$/fd/, you see where STDOUT (with fd 1) and STDERR (with fd 2), are going for the current process:



      $ ls -l /proc/$$/fd/
      total 0
      lrwx------ 1 bon bon 64 Jul 24 18:19 0 -> /dev/pts/1
      lrwx------ 1 bon bon 64 Jul 24 18:19 1 -> /dev/pts/1
      lrwx------ 1 bon bon 64 Jul 24 07:41 2 -> /dev/pts/1
      lrwx------ 1 bon bon 64 Jul 24 18:19 255 -> /dev/pts/1


      Let's create a small shell script that shows where your file descriptors are pointed. This way, we always get the state when calling ls, including any redirection from the calling shell.



      $ cat > lookfd.sh
      #!/bin/sh
      ls -l /proc/$$/fd/
      ^D
      $ chmod +x lookfd.sh


      (With CtrlD, you send an end-of-file and so stop the cat command reading from STDIN.)



      Now, call this script with varying combinations of redirection:



      $ ./lookfd.sh 
      total 0
      lrwx------ 1 bon bon 64 Jul 24 19:08 0 -> /dev/pts/1
      lrwx------ 1 bon bon 64 Jul 24 19:08 1 -> /dev/pts/1
      lrwx------ 1 bon bon 64 Jul 24 19:08 2 -> /dev/pts/1
      lr-x------ 1 bon bon 64 Jul 24 19:08 255 -> /home/bon/lookfd.sh
      $ ./lookfd.sh > foo.out
      $ cat foo.out
      total 0
      lrwx------ 1 bon bon 64 Jul 24 19:10 0 -> /dev/pts/1
      l-wx------ 1 bon bon 64 Jul 24 19:10 1 -> /home/bon/foo.out
      lrwx------ 1 bon bon 64 Jul 24 19:10 2 -> /dev/pts/1
      lr-x------ 1 bon bon 64 Jul 24 19:10 255 -> /home/bon/lookfd.sh
      $ ./lookfd.sh 2>&1 > foo.out
      $ cat foo.out
      total 0
      lrwx------ 1 bon bon 64 Jul 24 19:10 0 -> /dev/pts/1
      l-wx------ 1 bon bon 64 Jul 24 19:10 1 -> /home/bon/foo.out
      lrwx------ 1 bon bon 64 Jul 24 19:10 2 -> /dev/pts/1
      lr-x------ 1 bon bon 64 Jul 24 19:10 255 -> /home/bon/lookfd.sh
      $ ./lookfd.sh > foo.out 2>&1
      $ cat foo.out
      total 0
      lrwx------ 1 bon bon 64 Jul 24 19:11 0 -> /dev/pts/1
      l-wx------ 1 bon bon 64 Jul 24 19:11 1 -> /home/bon/foo.out
      l-wx------ 1 bon bon 64 Jul 24 19:11 2 -> /home/bon/foo.out
      lr-x------ 1 bon bon 64 Jul 24 19:11 255 -> /home/bon/lookfd.sh


      You can see, that the file descriptors 1 (for STDOUT) and 2 (for STDERR) vary. For fun, you could also redirect STDIN and see the result:



      $ ./lookfd.sh < /dev/zero
      total 0
      lr-x------ 1 bon bon 64 Jul 24 19:18 0 -> /dev/zero
      lrwx------ 1 bon bon 64 Jul 24 19:18 1 -> /dev/pts/1
      lrwx------ 1 bon bon 64 Jul 24 19:18 2 -> /dev/pts/1
      lr-x------ 1 bon bon 64 Jul 24 19:18 255 -> /home/bon/lookfd.sh


      (Question left to the reader: Where does file descriptor 255 point? ;-))







      share|improve this answer















      share|improve this answer




      share|improve this answer








      edited Jul 24 '13 at 17:48









      slm

      271k77 gold badges588 silver badges732 bronze badges




      271k77 gold badges588 silver badges732 bronze badges










      answered Jul 24 '13 at 17:33









      DubuDubu

      2,65512 silver badges24 bronze badges




      2,65512 silver badges24 bronze badges
















      • +1 - excellent answer. Extremely well written and terrific examples. Thank you!!!

        – slm
        Jul 24 '13 at 18:50











      • I see, I think my misunderstanding was that the redirection would be persistent for all following commands, so that any STDERR for the rest of the line would go to STDOUT.

        – Gregg Leventhal
        Jul 31 '13 at 13:56



















      • +1 - excellent answer. Extremely well written and terrific examples. Thank you!!!

        – slm
        Jul 24 '13 at 18:50











      • I see, I think my misunderstanding was that the redirection would be persistent for all following commands, so that any STDERR for the rest of the line would go to STDOUT.

        – Gregg Leventhal
        Jul 31 '13 at 13:56

















      +1 - excellent answer. Extremely well written and terrific examples. Thank you!!!

      – slm
      Jul 24 '13 at 18:50





      +1 - excellent answer. Extremely well written and terrific examples. Thank you!!!

      – slm
      Jul 24 '13 at 18:50













      I see, I think my misunderstanding was that the redirection would be persistent for all following commands, so that any STDERR for the rest of the line would go to STDOUT.

      – Gregg Leventhal
      Jul 31 '13 at 13:56





      I see, I think my misunderstanding was that the redirection would be persistent for all following commands, so that any STDERR for the rest of the line would go to STDOUT.

      – Gregg Leventhal
      Jul 31 '13 at 13:56













      2


















      No, the manual is right.



      If at first 1 points to the terminal, and 2 also to the terminal, then:



      command  2>&1   1>somewhere


      redirection evaluatino will happen from left to right.



      So it will FIRST evaluate 2>&1, and thus FIRST copy what fd 1 used to point to (ie, the file descriptor of the terminal, usually /dev/tty) into fd 2.



      So at that point fd 2 now points to where fd 1 used to point to (the terminal)



      And THEN it evaluates the 1>somewhere part, and thus will copy the file descriptor of somewhere in fd 1 (so at that point, fd 1 now points to somewhere, and fd 2 still points to the terminal)



      So it does indeed print 1 into "somewhere" and 2 into the terminal, as 2 was duplicated from 1 BEFORE 1 has been changed.



      The other order:



      command  1>somewhere 2>&1


      will first redirect fd 1 to somewhere, and then copy that same reference into fd 2, so at the end 2 also points to somewhere.
      But they are not "linked" from now on. Each can still be redirected separately.



      ex:



      command  1>somewhere 2>&1
      exec 2>/dev/null


      At the end of that one, fd 1 points to somewhere, and fd 2 is directed to /dev/null



      Usual names for fd 1 is STDOUT (standard output), and usual name for fd 2 is STDERR (standard error, as it's commonly used to display errors without interfering with STDOUT)






      share|improve this answer





























      • @Michael-mrozek : thanks for the edit, but I insist on saying "copy" instead of "duplicate" as "duplicate" could lead one to believe that from now on both are "the same thing", which is not true. ex: cmd 1>somewhere 2>&1 ; exec 2>/dev/null : after the exec, only 2 has been redirected to /dev/null (1 is still going to "somewhere"). I do need help to come up with a way to say "what 1 points to" instead of "the fd 1", however... as that is also confusing...

        – Olivier Dulac
        Jul 24 '13 at 17:19








      • 1





        I'm not sure what you mean; you're the one who changed it from "copy" to "duplicate". All I did was capitalize and format things, I didn't change a word

        – Michael Mrozek
        Jul 24 '13 at 17:23











      • doh... ^^ sorry. And I edited again to reformulate to make more precise what is copied into what ^^

        – Olivier Dulac
        Jul 24 '13 at 17:26
















      2


















      No, the manual is right.



      If at first 1 points to the terminal, and 2 also to the terminal, then:



      command  2>&1   1>somewhere


      redirection evaluatino will happen from left to right.



      So it will FIRST evaluate 2>&1, and thus FIRST copy what fd 1 used to point to (ie, the file descriptor of the terminal, usually /dev/tty) into fd 2.



      So at that point fd 2 now points to where fd 1 used to point to (the terminal)



      And THEN it evaluates the 1>somewhere part, and thus will copy the file descriptor of somewhere in fd 1 (so at that point, fd 1 now points to somewhere, and fd 2 still points to the terminal)



      So it does indeed print 1 into "somewhere" and 2 into the terminal, as 2 was duplicated from 1 BEFORE 1 has been changed.



      The other order:



      command  1>somewhere 2>&1


      will first redirect fd 1 to somewhere, and then copy that same reference into fd 2, so at the end 2 also points to somewhere.
      But they are not "linked" from now on. Each can still be redirected separately.



      ex:



      command  1>somewhere 2>&1
      exec 2>/dev/null


      At the end of that one, fd 1 points to somewhere, and fd 2 is directed to /dev/null



      Usual names for fd 1 is STDOUT (standard output), and usual name for fd 2 is STDERR (standard error, as it's commonly used to display errors without interfering with STDOUT)






      share|improve this answer





























      • @Michael-mrozek : thanks for the edit, but I insist on saying "copy" instead of "duplicate" as "duplicate" could lead one to believe that from now on both are "the same thing", which is not true. ex: cmd 1>somewhere 2>&1 ; exec 2>/dev/null : after the exec, only 2 has been redirected to /dev/null (1 is still going to "somewhere"). I do need help to come up with a way to say "what 1 points to" instead of "the fd 1", however... as that is also confusing...

        – Olivier Dulac
        Jul 24 '13 at 17:19








      • 1





        I'm not sure what you mean; you're the one who changed it from "copy" to "duplicate". All I did was capitalize and format things, I didn't change a word

        – Michael Mrozek
        Jul 24 '13 at 17:23











      • doh... ^^ sorry. And I edited again to reformulate to make more precise what is copied into what ^^

        – Olivier Dulac
        Jul 24 '13 at 17:26














      2














      2










      2









      No, the manual is right.



      If at first 1 points to the terminal, and 2 also to the terminal, then:



      command  2>&1   1>somewhere


      redirection evaluatino will happen from left to right.



      So it will FIRST evaluate 2>&1, and thus FIRST copy what fd 1 used to point to (ie, the file descriptor of the terminal, usually /dev/tty) into fd 2.



      So at that point fd 2 now points to where fd 1 used to point to (the terminal)



      And THEN it evaluates the 1>somewhere part, and thus will copy the file descriptor of somewhere in fd 1 (so at that point, fd 1 now points to somewhere, and fd 2 still points to the terminal)



      So it does indeed print 1 into "somewhere" and 2 into the terminal, as 2 was duplicated from 1 BEFORE 1 has been changed.



      The other order:



      command  1>somewhere 2>&1


      will first redirect fd 1 to somewhere, and then copy that same reference into fd 2, so at the end 2 also points to somewhere.
      But they are not "linked" from now on. Each can still be redirected separately.



      ex:



      command  1>somewhere 2>&1
      exec 2>/dev/null


      At the end of that one, fd 1 points to somewhere, and fd 2 is directed to /dev/null



      Usual names for fd 1 is STDOUT (standard output), and usual name for fd 2 is STDERR (standard error, as it's commonly used to display errors without interfering with STDOUT)






      share|improve this answer
















      No, the manual is right.



      If at first 1 points to the terminal, and 2 also to the terminal, then:



      command  2>&1   1>somewhere


      redirection evaluatino will happen from left to right.



      So it will FIRST evaluate 2>&1, and thus FIRST copy what fd 1 used to point to (ie, the file descriptor of the terminal, usually /dev/tty) into fd 2.



      So at that point fd 2 now points to where fd 1 used to point to (the terminal)



      And THEN it evaluates the 1>somewhere part, and thus will copy the file descriptor of somewhere in fd 1 (so at that point, fd 1 now points to somewhere, and fd 2 still points to the terminal)



      So it does indeed print 1 into "somewhere" and 2 into the terminal, as 2 was duplicated from 1 BEFORE 1 has been changed.



      The other order:



      command  1>somewhere 2>&1


      will first redirect fd 1 to somewhere, and then copy that same reference into fd 2, so at the end 2 also points to somewhere.
      But they are not "linked" from now on. Each can still be redirected separately.



      ex:



      command  1>somewhere 2>&1
      exec 2>/dev/null


      At the end of that one, fd 1 points to somewhere, and fd 2 is directed to /dev/null



      Usual names for fd 1 is STDOUT (standard output), and usual name for fd 2 is STDERR (standard error, as it's commonly used to display errors without interfering with STDOUT)







      share|improve this answer















      share|improve this answer




      share|improve this answer








      edited Jul 24 '13 at 17:31

























      answered Jul 24 '13 at 17:08









      Olivier DulacOlivier Dulac

      3,99313 silver badges25 bronze badges




      3,99313 silver badges25 bronze badges
















      • @Michael-mrozek : thanks for the edit, but I insist on saying "copy" instead of "duplicate" as "duplicate" could lead one to believe that from now on both are "the same thing", which is not true. ex: cmd 1>somewhere 2>&1 ; exec 2>/dev/null : after the exec, only 2 has been redirected to /dev/null (1 is still going to "somewhere"). I do need help to come up with a way to say "what 1 points to" instead of "the fd 1", however... as that is also confusing...

        – Olivier Dulac
        Jul 24 '13 at 17:19








      • 1





        I'm not sure what you mean; you're the one who changed it from "copy" to "duplicate". All I did was capitalize and format things, I didn't change a word

        – Michael Mrozek
        Jul 24 '13 at 17:23











      • doh... ^^ sorry. And I edited again to reformulate to make more precise what is copied into what ^^

        – Olivier Dulac
        Jul 24 '13 at 17:26



















      • @Michael-mrozek : thanks for the edit, but I insist on saying "copy" instead of "duplicate" as "duplicate" could lead one to believe that from now on both are "the same thing", which is not true. ex: cmd 1>somewhere 2>&1 ; exec 2>/dev/null : after the exec, only 2 has been redirected to /dev/null (1 is still going to "somewhere"). I do need help to come up with a way to say "what 1 points to" instead of "the fd 1", however... as that is also confusing...

        – Olivier Dulac
        Jul 24 '13 at 17:19








      • 1





        I'm not sure what you mean; you're the one who changed it from "copy" to "duplicate". All I did was capitalize and format things, I didn't change a word

        – Michael Mrozek
        Jul 24 '13 at 17:23











      • doh... ^^ sorry. And I edited again to reformulate to make more precise what is copied into what ^^

        – Olivier Dulac
        Jul 24 '13 at 17:26

















      @Michael-mrozek : thanks for the edit, but I insist on saying "copy" instead of "duplicate" as "duplicate" could lead one to believe that from now on both are "the same thing", which is not true. ex: cmd 1>somewhere 2>&1 ; exec 2>/dev/null : after the exec, only 2 has been redirected to /dev/null (1 is still going to "somewhere"). I do need help to come up with a way to say "what 1 points to" instead of "the fd 1", however... as that is also confusing...

      – Olivier Dulac
      Jul 24 '13 at 17:19







      @Michael-mrozek : thanks for the edit, but I insist on saying "copy" instead of "duplicate" as "duplicate" could lead one to believe that from now on both are "the same thing", which is not true. ex: cmd 1>somewhere 2>&1 ; exec 2>/dev/null : after the exec, only 2 has been redirected to /dev/null (1 is still going to "somewhere"). I do need help to come up with a way to say "what 1 points to" instead of "the fd 1", however... as that is also confusing...

      – Olivier Dulac
      Jul 24 '13 at 17:19






      1




      1





      I'm not sure what you mean; you're the one who changed it from "copy" to "duplicate". All I did was capitalize and format things, I didn't change a word

      – Michael Mrozek
      Jul 24 '13 at 17:23





      I'm not sure what you mean; you're the one who changed it from "copy" to "duplicate". All I did was capitalize and format things, I didn't change a word

      – Michael Mrozek
      Jul 24 '13 at 17:23













      doh... ^^ sorry. And I edited again to reformulate to make more precise what is copied into what ^^

      – Olivier Dulac
      Jul 24 '13 at 17:26





      doh... ^^ sorry. And I edited again to reformulate to make more precise what is copied into what ^^

      – Olivier Dulac
      Jul 24 '13 at 17:26











      1


















      I think the confusing part here is the misapprehension that redirecting stderr to stdout actually connects the two streams.



      A perfectly reasonable idea but what happens when you write 2>&1 is stderr takes a peekaboo at what stdout is writing to and writes to the same place itself. Therefore if you subsequently tell stdout to go write somewhere else it has no effect on the destination of stderr which has already been moved.



      I think it's a tad counterintuitive myself but that's how it works. Set up where you want to write to first then tell everyone "copy me".
      Hope that clarifies...






      share|improve this answer

































        1


















        I think the confusing part here is the misapprehension that redirecting stderr to stdout actually connects the two streams.



        A perfectly reasonable idea but what happens when you write 2>&1 is stderr takes a peekaboo at what stdout is writing to and writes to the same place itself. Therefore if you subsequently tell stdout to go write somewhere else it has no effect on the destination of stderr which has already been moved.



        I think it's a tad counterintuitive myself but that's how it works. Set up where you want to write to first then tell everyone "copy me".
        Hope that clarifies...






        share|improve this answer































          1














          1










          1









          I think the confusing part here is the misapprehension that redirecting stderr to stdout actually connects the two streams.



          A perfectly reasonable idea but what happens when you write 2>&1 is stderr takes a peekaboo at what stdout is writing to and writes to the same place itself. Therefore if you subsequently tell stdout to go write somewhere else it has no effect on the destination of stderr which has already been moved.



          I think it's a tad counterintuitive myself but that's how it works. Set up where you want to write to first then tell everyone "copy me".
          Hope that clarifies...






          share|improve this answer
















          I think the confusing part here is the misapprehension that redirecting stderr to stdout actually connects the two streams.



          A perfectly reasonable idea but what happens when you write 2>&1 is stderr takes a peekaboo at what stdout is writing to and writes to the same place itself. Therefore if you subsequently tell stdout to go write somewhere else it has no effect on the destination of stderr which has already been moved.



          I think it's a tad counterintuitive myself but that's how it works. Set up where you want to write to first then tell everyone "copy me".
          Hope that clarifies...







          share|improve this answer















          share|improve this answer




          share|improve this answer








          edited Jul 30 '13 at 1:03









          jasonwryan

          53.5k14 gold badges141 silver badges195 bronze badges




          53.5k14 gold badges141 silver badges195 bronze badges










          answered Jul 30 '13 at 0:26









          jrichemontjrichemont

          112 bronze badges




          112 bronze badges


























              0


















              DUPLICATION...



              is important, but rather in the sense that it is the source of much confusion. It is really quite simple. This answer is just a "radical" illustration.



              The accepted answer is good, but too long and it emphasizes "duplicatition".



              The Q wisely ends with:




              The use of the word duplication seems a little strange to me in
              this context. Perhaps that is throwing me.




              I use bash notation and define variables "one" and "two" as filehandles "1" and "2". The (output) redirection operator > is an assignment =. & and $ mean "value" of.



              The man bash examples (with default "1" added)



              ls 1>dirlist 2>&1      # both to dirlist
              ls 2>&1 1>dirlist # 1 to dirlist, 2 stays on tty/screen


              become:



              one=dirlist  two=$one


              and



              two=$one   one=dirlist


              And even this is non-automatic to me, and some others I guess. The first line leaves you with $one and $two both containing "dirlist". Of course.



              The second line starts with a useless assignment. Both start by definition with "TTY" (a bit symbolic) as their direction; no value is changed by this assignment, and with variables as with filehandles, nothing is magically linked. Variable two is not affected by the following one=dirlist. Of course not.



              Sombody here (6 years ago) suggested "point to" instead of "copy" or "duplicate", and then realized: that would be confusing too.



              This duplication or pointer semantic is not even needed. Maybe it's the ampersand that needs more attention. The "value of" operator/token/whatever.



              If - and only if - you are looking for a way to get a surprising job number on your console, then a "done" message plus as a bonus a file named "2", then you go:



              ls 1>2& 2>/dev/null


              It reads naturally as "copy"/"duplicate" 1 to 2, and then both together to null. But the idea is wrong, and also the syntax. (but no syntax error, it is valid)



              The right way to plan it is to redirect any of the two to null, and then redirect the OTHER to the SAME place:



              ls 1>/dev/null 2>&1
              # or
              ls 2>/dev/null 1>&2


              (the leading "1" can be left away)



              (OK the acc. A is not too long, but is too much of a list - or: very good visualisation, not so good explanation)






              share|improve this answer































                0


















                DUPLICATION...



                is important, but rather in the sense that it is the source of much confusion. It is really quite simple. This answer is just a "radical" illustration.



                The accepted answer is good, but too long and it emphasizes "duplicatition".



                The Q wisely ends with:




                The use of the word duplication seems a little strange to me in
                this context. Perhaps that is throwing me.




                I use bash notation and define variables "one" and "two" as filehandles "1" and "2". The (output) redirection operator > is an assignment =. & and $ mean "value" of.



                The man bash examples (with default "1" added)



                ls 1>dirlist 2>&1      # both to dirlist
                ls 2>&1 1>dirlist # 1 to dirlist, 2 stays on tty/screen


                become:



                one=dirlist  two=$one


                and



                two=$one   one=dirlist


                And even this is non-automatic to me, and some others I guess. The first line leaves you with $one and $two both containing "dirlist". Of course.



                The second line starts with a useless assignment. Both start by definition with "TTY" (a bit symbolic) as their direction; no value is changed by this assignment, and with variables as with filehandles, nothing is magically linked. Variable two is not affected by the following one=dirlist. Of course not.



                Sombody here (6 years ago) suggested "point to" instead of "copy" or "duplicate", and then realized: that would be confusing too.



                This duplication or pointer semantic is not even needed. Maybe it's the ampersand that needs more attention. The "value of" operator/token/whatever.



                If - and only if - you are looking for a way to get a surprising job number on your console, then a "done" message plus as a bonus a file named "2", then you go:



                ls 1>2& 2>/dev/null


                It reads naturally as "copy"/"duplicate" 1 to 2, and then both together to null. But the idea is wrong, and also the syntax. (but no syntax error, it is valid)



                The right way to plan it is to redirect any of the two to null, and then redirect the OTHER to the SAME place:



                ls 1>/dev/null 2>&1
                # or
                ls 2>/dev/null 1>&2


                (the leading "1" can be left away)



                (OK the acc. A is not too long, but is too much of a list - or: very good visualisation, not so good explanation)






                share|improve this answer





























                  0














                  0










                  0









                  DUPLICATION...



                  is important, but rather in the sense that it is the source of much confusion. It is really quite simple. This answer is just a "radical" illustration.



                  The accepted answer is good, but too long and it emphasizes "duplicatition".



                  The Q wisely ends with:




                  The use of the word duplication seems a little strange to me in
                  this context. Perhaps that is throwing me.




                  I use bash notation and define variables "one" and "two" as filehandles "1" and "2". The (output) redirection operator > is an assignment =. & and $ mean "value" of.



                  The man bash examples (with default "1" added)



                  ls 1>dirlist 2>&1      # both to dirlist
                  ls 2>&1 1>dirlist # 1 to dirlist, 2 stays on tty/screen


                  become:



                  one=dirlist  two=$one


                  and



                  two=$one   one=dirlist


                  And even this is non-automatic to me, and some others I guess. The first line leaves you with $one and $two both containing "dirlist". Of course.



                  The second line starts with a useless assignment. Both start by definition with "TTY" (a bit symbolic) as their direction; no value is changed by this assignment, and with variables as with filehandles, nothing is magically linked. Variable two is not affected by the following one=dirlist. Of course not.



                  Sombody here (6 years ago) suggested "point to" instead of "copy" or "duplicate", and then realized: that would be confusing too.



                  This duplication or pointer semantic is not even needed. Maybe it's the ampersand that needs more attention. The "value of" operator/token/whatever.



                  If - and only if - you are looking for a way to get a surprising job number on your console, then a "done" message plus as a bonus a file named "2", then you go:



                  ls 1>2& 2>/dev/null


                  It reads naturally as "copy"/"duplicate" 1 to 2, and then both together to null. But the idea is wrong, and also the syntax. (but no syntax error, it is valid)



                  The right way to plan it is to redirect any of the two to null, and then redirect the OTHER to the SAME place:



                  ls 1>/dev/null 2>&1
                  # or
                  ls 2>/dev/null 1>&2


                  (the leading "1" can be left away)



                  (OK the acc. A is not too long, but is too much of a list - or: very good visualisation, not so good explanation)






                  share|improve this answer














                  DUPLICATION...



                  is important, but rather in the sense that it is the source of much confusion. It is really quite simple. This answer is just a "radical" illustration.



                  The accepted answer is good, but too long and it emphasizes "duplicatition".



                  The Q wisely ends with:




                  The use of the word duplication seems a little strange to me in
                  this context. Perhaps that is throwing me.




                  I use bash notation and define variables "one" and "two" as filehandles "1" and "2". The (output) redirection operator > is an assignment =. & and $ mean "value" of.



                  The man bash examples (with default "1" added)



                  ls 1>dirlist 2>&1      # both to dirlist
                  ls 2>&1 1>dirlist # 1 to dirlist, 2 stays on tty/screen


                  become:



                  one=dirlist  two=$one


                  and



                  two=$one   one=dirlist


                  And even this is non-automatic to me, and some others I guess. The first line leaves you with $one and $two both containing "dirlist". Of course.



                  The second line starts with a useless assignment. Both start by definition with "TTY" (a bit symbolic) as their direction; no value is changed by this assignment, and with variables as with filehandles, nothing is magically linked. Variable two is not affected by the following one=dirlist. Of course not.



                  Sombody here (6 years ago) suggested "point to" instead of "copy" or "duplicate", and then realized: that would be confusing too.



                  This duplication or pointer semantic is not even needed. Maybe it's the ampersand that needs more attention. The "value of" operator/token/whatever.



                  If - and only if - you are looking for a way to get a surprising job number on your console, then a "done" message plus as a bonus a file named "2", then you go:



                  ls 1>2& 2>/dev/null


                  It reads naturally as "copy"/"duplicate" 1 to 2, and then both together to null. But the idea is wrong, and also the syntax. (but no syntax error, it is valid)



                  The right way to plan it is to redirect any of the two to null, and then redirect the OTHER to the SAME place:



                  ls 1>/dev/null 2>&1
                  # or
                  ls 2>/dev/null 1>&2


                  (the leading "1" can be left away)



                  (OK the acc. A is not too long, but is too much of a list - or: very good visualisation, not so good explanation)







                  share|improve this answer













                  share|improve this answer




                  share|improve this answer










                  answered 1 hour ago









                  rastafilerastafile

                  1435 bronze badges




                  1435 bronze badges


































                      draft saved

                      draft discarded



















































                      Thanks for contributing an answer to Unix & Linux Stack Exchange!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f84279%2fis-this-a-typo-in-bash-manuals-redirection-section%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown









                      Popular posts from this blog

                      Hudson River Historic District Contents Geography History The district today Aesthetics Cultural...

                      The number designs the writing. Feandra Aversely Definition: The act of ingrafting a sprig or shoot of one...

                      Ayherre Geografie Demografie Externe links Navigatiemenu43° 23′ NB, 1° 15′ WL43° 23′ NB, 1°...