美文网首页
重定向(redirection)

重定向(redirection)

作者: littleDinosaur | 来源:发表于2017-02-14 10:28 被阅读0次

    Chapter 20. I/O Redirection

    Table of Contents
    20.1. Using exec
    20.2. Redirecting Code Blocks
    20.3. Applications

    There are always three default files [1] open, stdin (the keyboard), stdout (the screen), and stderr (error messages output to the screen). These, and any other open files, can be redirected. Redirection simply means capturing output from a file, command, program, script, or even code block within a script (see Example 3-1 and Example 3-2) and sending it as input to another file, command, program, or script.

    Each open file gets assigned a file descriptor. [2] The file descriptors for stdin, stdout, and stderr are 0, 1, and 2, respectively. For opening additional files, there remain descriptors 3 to 9. It is sometimes useful to assign one of these additional file descriptors to stdin, stdout, or stderr as a temporary duplicate link. [3] This simplifies restoration to normal after complex redirection and reshuffling (see Example 20-1).

    COMMAND_OUTPUT >
    # Redirect stdout to a file.
    # Creates the file if not present, otherwise overwrites it.

      ls -lR > dir-tree.list
      # Creates a file containing a listing of the directory tree.
    

    : > filename
    # The > truncates file "filename" to zero length.
    # If file not present, creates zero-length file (same effect as 'touch').
    # The : serves as a dummy placeholder, producing no output.

    filename
    # The > truncates file "filename" to zero length.
    # If file not present, creates zero-length file (same effect as 'touch').
    # (Same result as ": >", above, but this does not work with some shells.)

    COMMAND_OUTPUT >>
    # Redirect stdout to a file.
    # Creates the file if not present, otherwise appends to it.

      # Single-line redirection commands (affect only the line they are on):
      # --------------------------------------------------------------------
    

    1>filename
    # Redirect stdout to file "filename."
    1>>filename
    # Redirect and append stdout to file "filename."
    2>filename
    # Redirect stderr to file "filename."
    2>>filename
    # Redirect and append stderr to file "filename."
    &>filename
    # Redirect both stdout and stderr to file "filename."
    # This operator is now functional, as of Bash 4, final release.

    M>N
    # "M" is a file descriptor, which defaults to 1, if not explicitly set.
    # "N" is a filename.
    # File descriptor "M" is redirect to file "N."
    M>&N
    # "M" is a file descriptor, which defaults to 1, if not set.
    # "N" is another file descriptor.

      #==============================================================================
    
      # Redirecting stdout, one line at a time.
      LOGFILE=script.log
    
      echo "This statement is sent to the log file, \"$LOGFILE\"." 1>$LOGFILE
      echo "This statement is appended to \"$LOGFILE\"." 1>>$LOGFILE
      echo "This statement is also appended to \"$LOGFILE\"." 1>>$LOGFILE
      echo "This statement is echoed to stdout, and will not appear in \"$LOGFILE\"."
      # These redirection commands automatically "reset" after each line.
    
    
    
      # Redirecting stderr, one line at a time.
      ERRORFILE=script.errors
    
      bad_command1 2>$ERRORFILE       #  Error message sent to $ERRORFILE.
      bad_command2 2>>$ERRORFILE      #  Error message appended to $ERRORFILE.
      bad_command3                    #  Error message echoed to stderr,
                                      #+ and does not appear in $ERRORFILE.
      # These redirection commands also automatically "reset" after each line.
      #=======================================================================
    

    2>&1
    # Redirects stderr to stdout.
    # Error messages get sent to same place as standard output.
    >>filename 2>&1
    bad_command >>filename 2>&1
    # Appends both stdout and stderr to the file "filename" ...
    2>&1 | [command(s)]
    bad_command 2>&1 | awk '{print $5}' # found
    # Sends stderr through a pipe.
    # |& was added to Bash 4 as an abbreviation for 2>&1 |.

    i>&j
    # Redirects file descriptor i to j.
    # All output of file pointed to by i gets sent to file pointed to by j.

    &j
    # Redirects, by default, file descriptor 1 (stdout) to j.
    # All stdout gets sent to file pointed to by j.

    0< FILENAME
    < FILENAME
    # Accept input from a file.
    # Companion command to ">", and often used in combination with it.
    #
    # grep search-word <filename

    [j]<>filename
    # Open file "filename" for reading and writing,
    #+ and assign file descriptor "j" to it.
    # If "filename" does not exist, create it.
    # If file descriptor "j" is not specified, default to fd 0, stdin.
    #
    # An application of this is writing at a specified place in a file.
    echo 1234567890 > File # Write string to "File".
    exec 3<> File # Open "File" and assign fd 3 to it.
    read -n 4 <&3 # Read only 4 characters.
    echo -n . >&3 # Write a decimal point there.
    exec 3>&- # Close fd 3.
    cat File # ==> 1234.67890
    # Random access, by golly.

    |
    # Pipe.
    # General purpose process and command chaining tool.
    # Similar to ">", but more general in effect.
    # Useful for chaining commands, scripts, files, and programs together.
    cat *.txt | sort | uniq > result-file
    # Sorts the output of all the .txt files and deletes duplicate lines,
    # finally saves results to "result-file".

    Multiple instances of input and output redirection and/or pipes can be combined in a single command line.

    command < input-file > output-file

    Or the equivalent:

    < input-file command > output-file # Although this is non-standard.

    command1 | command2 | command3 > output-file

    See Example 16-31 and Example A-14.

    Multiple output streams may be redirected to one file.

    ls -yz >> command.log 2>&1

    Capture result of illegal options "yz" in file "command.log."

    Because stderr is redirected to the file,

    + any error messages will also be there.

    Note, however, that the following does not give the same result.

    ls -yz 2>&1 >> command.log

    Outputs an error message, but does not write to file.

    More precisely, the command output (in this case, null)

    + writes to the file, but the error message goes only to stdout.

    If redirecting both stdout and stderr,

    + the order of the commands makes a difference.

    Closing File Descriptors

    n<&-

    Close input file descriptor n.
    

    0<&-, <&-

    Close stdin.
    

    n>&-

    Close output file descriptor n.
    

    1>&-, >&-

    Close stdout.
    

    Child processes inherit open file descriptors. This is why pipes work. To prevent an fd from being inherited, close it.

    Redirecting only stderr to a pipe.

    exec 3>&1 # Save current "value" of stdout.
    ls -l 2>&1 >&3 3>&- | grep bad 3>&- # Close fd 3 for 'grep' (but not 'ls').

    ^^^^ ^^^^

    exec 3>&- # Now close it for the remainder of the script.

    Thanks, S.C.

    相关文章

      网友评论

          本文标题:重定向(redirection)

          本文链接:https://www.haomeiwen.com/subject/dkrxwttx.html