and 2 echo messages" I came across a differe...">

Difference between redirection position in messages "echo" and "2", "echo message" and "2" and "> and 2 echo messages"

I came across a different location for the redirect symbol ( >

, <

). For example:

echo>&2 message
message

echo message >&2
message

>&2 echo message
message

      

For all forms I got the same result. I used file redirection ( >filename

) instead of stream redirection ( >&2

). Also I used input redirection ( <filename

). The result is the same in bash and windows cmd.

Is there a difference in the location of the redirect?

PS I've only seen the "echo message> & 2" form in the books.

+3


source to share


3 answers


Redirecting the flow X>&Y

in the shell uses a system call dup2(2)

to replace one file descriptor associated with the flow ( stdin

, stdout

, stderr

or something else) with the other.

Basically, it 2>&1

literally dup2(2, 1)

means "to attach FD 2 to what is currently connected to FD 1, possibly by closing FD 2 first".



This has two essential properties:

  • For this to work, the file descriptor to replace the existing one with must already represent the file / device we want to bind our descriptor to.

  • As soon as we replaced one file descriptor with another and then reopened that file descriptor used as a replacement for some other file / device, both file descriptors are disabled. Hence, order matters:

    foo >/dev/null 2>&1
    
          

    ok because he's mostly

    // 1) do >/dev/null
    close(1);
    fd = open("/dev/null", O_WRONLY, 0666); // fd will be == 1 on success.
    // 2) do 2>&1
    dup2(2, 1);
    
          

    so that FDs 2 and 1 are open in the same file "/ dev / null", while

    foo 2>&1 >/dev/null
    
          

    will first attach fd 2 to the same file that fd 1 is attached to, and then immediately bind fd 1 to the new file - /dev/null

    - leaving fd 2 still open for whatever fd 1 is attached to during the first redirect:

    // 1) do 2>&1
    dup2(2, 1);
    // 2) do >/dev/null
    close(1);
    // FD 2 is still open to the same file FD 1 was just before closing.
    fd = open("/dev/null", O_WRONLY, 0666); // fd will be == 1 on success
    // Now both FDs are opened to different files.
    
          

+1


source


have a look at the bash guide , especially the file descriptor section. commands redirect standard input to standard error. if you filter 2>/dev/null

, you should see the messages disappear. hope this helps.



0


source


For simple commands

echo >&2 message

- the only one that differs, and it differs only in that it is incompatible with the POSIX sh specification; support for redirection at any position - bash extension.

>&2 echo message

and are echo message >&2

exactly the same, and support for both is guaranteed in the POSIX sh standard.


For compound commands

Redirects are only valid at the end of compound commands. I.e:

while read -r line; do printf '%s\n' "$line"; done <file

      

... is valid but

<file while read -r line; do printf '%s\n' "$line"; done

      

... POSIX support is not guaranteed.

Positions within a compound command will apply to individual subcommands, so a bash extension that allows redirects to any position within a command is meaningless here.


Formal grammar

The following is a quote from the POSIX shell grammar specification:

cmd_prefix       :            io_redirect
                 | cmd_prefix io_redirect
                 |            ASSIGNMENT_WORD
                 | cmd_prefix ASSIGNMENT_WORD
                 ;
cmd_suffix       :            io_redirect
                 | cmd_suffix io_redirect
                 |            WORD
                 | cmd_suffix WORD
                 ;
simple_command   : cmd_prefix cmd_word cmd_suffix
                 | cmd_prefix cmd_word
                 | cmd_prefix
                 | cmd_name cmd_suffix
                 | cmd_name
                 ;
command          : simple_command
                 | compound_command
                 | compound_command redirect_list
                 | function_definition
redirect_list    :               io_redirect
                 | redirect_list io_redirect
                 ;

      

Thus, in a shell that implements POSIX sh without extensions:

  • Permissions are allowed within cmd_prefix

    or << 27>, i.e. at the beginning or end of a simple command
  • Redistribution is allowed at the end (only) of a compound command.
0


source







All Articles