精华内容
下载资源
问答
  • Linux重定向程序:指令+数据读入数据: Input输出数据: Output打开的文件都有一个fd: file descriptor (文件描述符)Linux给程序提供三种I/O设备标准输入( STDIN) 0 默认接受来自键盘的输入标准输出( STDOUT) 1默认...

    Linux重定向

    程序:指令+数据

    读入数据: Input

    输出数据: Output

    打开的文件都有一个fd: file descriptor (文件描述符)

    Linux给程序提供三种I/O设备

    标准输入( STDIN)   0  默认接受来自键盘的输入

    标准输出( STDOUT)     1默认输出到终端窗口

    标准错误( STDERR)      2默认输出到终端窗口

    [root@localhost /testdir]# ll /dev/std*

    lrwxrwxrwx. 1 root root 15 Aug 28 22:22 /dev/stderr -> /proc/self/fd/2

    lrwxrwxrwx. 1 root root 15 Aug 28 22:22 /dev/stdin -> /proc/self/fd/0

    lrwxrwxrwx. 1 root root 15 Aug 28 22:22 /dev/stdout -> /proc/self/fd/1

    I/O重定向:改变默认位置

    STDOUT和STDERR可以被重定向到文件:

    命令 操作符号 文件名

    支持的操作符号包括:

    >      把STDOUT重定向到文件

    2>     把STDERR重定向到文件

    &>     把所有输出重定向到文件

    > 文件内容会被覆盖

    # set -C: 禁止将内容覆盖已有文件,但可追加

    强制覆盖: >|

    # set +C: 允许覆盖

    >> 原有内容基础上,追加内容

    2>: 覆盖重定向错误输出数据流;

    2>>: 追加重定向错误输出数据流;

    标准输出和错误输出各自定向至不同位置:

    COMMAND > /path/to/file.out 2> /path/to/error.out

    合并标准输出和错误输出为同一个数据流进行重定向:

    &>:覆盖重定向

    &>>:追加重定向

    COMMAND > /path/to/file.out 2> &1 (顺序很重要)

    COMMAND >> /path/to/file.out 2>> &1

    find /etc -name passwd 2> /dev/null

    ():合并多个程序的STDOUT

    [root@localhost /testdir]# (cal 2016;cal 2017) > cal.txt    #将两个命令的结果输出到cal.txt文件中

    [root@localhost /testdir]# (date; lsdf) &> all.txt          #将标准输出和错误输出全部写入到all.txt文件中

    [root@localhost /testdir]# cat all.txt

    Mon Aug 29 20:04:27 CST 2016

    bash: lsdf: command not found...

    注意:

    1、shell遇到”>”操作符,会判断右边文件是否存在,如果存在就先删除,并且创建新文件。不存在直接创建。 无论左边命令执行是否成功。右边文件都会变为空。

    2、“>>”操作符,判断右边文件,如果不存在,先创建。以添加方式打开文件,会分配一个文件描述符[不特别指定,默认为1,2]然后,与左边的标准输出(1)或错误输出(2) 绑定。

    3、当命令执行完,绑定文件的描述符也自动失效。0,1,2又会空闲。

    4、一条命令启动,命令的输入,正确输出,错误输出,默认分别绑定0,1,2文件描述符。

    5、一条命令在执行前,先会检查输出是否正确,如果输出设备错误,将不会进行命令执行

    示例:

    [root@localhost /testdir]# set -C bs                    #禁止将内容覆盖已有文件

    [root@localhost /testdir]# echo "nnnnnnnnnn" > bs

    -bash: bs: cannot overwrite existing file

    [root@localhost /testdir]# echo "mmmmmmmmm" >| bs

    [root@localhost /testdir]# echo "nnnnnnnn" >> bs

    [root@localhost /testdir]# cat bs

    mmmmmmmmm

    nnnnnnnn

    [root@localhost /testdir]# set +C bs                    #允许覆盖

    [root@localhost /testdir]# echo "aaaaaaaa" > bs

    [root@localhost /testdir]# echo "Hello World" > wel    #覆盖写入

    [root@localhost /testdir]# echo "Hello" >> wel         #追加写入

    [root@localhost /testdir]# cat wel

    Hello World

    Hello

    [root@localhost /testdir]# cat < /etc/issue#从指定文件读取内容

    \S

    Kernel \r on an \m

    [root@localhost /testdir]# lsdfdf &> err.txt        #不管是标准输出还是错误输出都写入到err.txt文件中

    [root@localhost /testdir]# cat err.txt

    bash: lsdfdf: command not found...

    从文件中导入STDIN

    使用

    某些命令能够接受从文件中导入的STDIN:

    把/etc/issue中的小写字符都转换成写写字符

    [root@localhost /testdir]# tr 'a-z' 'A-Z' < /etc/issue

    \S

    KERNEL \R ON AN \M

    删除issue文件中的指定的字符

    [root@localhost /testdir]# tr -d 'a-h' < /etc/issue

    \S

    Krnl \r on n \m

    [root@localhost /testdir]# cat > t < test

    [root@localhost /testdir]# cat t

    1212121

    [root@localhost /testdir]# cat test

    1212121

    把多行发送给STDIN

    使用“ <

    直到 终止词 位置的所有文本都发送给STDIN

    有时被称为就地文本( heretext)

    [root@localhost /testdir]# cat > file <

    > hello

    > world

    > hi,

    > end

    [root@localhost /testdir]# cat file

    hello

    world

    hi,

    管道

    管道(使用符号“ |”表示)用来连接命令

    命令1 | 命令2 |命令3 |…

    将命令1的STDOUT发送给命令2的STDIN,命令2的STDOUT发送到命令3的STDIN

    STDERR默认不能通过管道转发,可利用2>&1或 |&实现

    最后一个命令会在当前shell进程的子shell进程中执行用来

    组合多种工具的功能

    [root@localhost /testdir]# ls

    all.txt  cal.txt  err.txt  file

    [root@localhost /testdir]# ls | tr 'a-z' 'A-Z'

    ALL.TXT

    CAL.TXT

    ERR.TXT

    FILE

    less:一页一页地查看输入:

    [root@localhost /testdir]# ls -l /etc/ | less#分页显示/etc目录下的列表

    mail: 通过电子邮件发送输入:

    [root@localhost /testdir]# echo "test mail" | mail -s test root#给root发送邮件

    lpr:把输入发送给打印机

    [root@localhost /testdir]# echo "test print" | lpr -P printer

    重定向到多个目标( tee)

    命令1 | tee文件名 |命令2

    把命令1的STDOUT保存在文件名中,然后管道输入给命令2

    使用:

    保存不同阶段的输出

    复杂管道的故障排除

    同时查看和记录输出

    [root@localhost /testdir]# ls | tee sc.txt | tr 'a-z' 'A-Z'

    ALL.TXT

    CAL.TXT

    ERR.TXT

    FILE

    [root@localhost /testdir]# cat sc.txt

    all.txt

    cal.txt

    err.txt

    file

    展开全文
  • Linux重定向

    2021-08-10 22:50:01
    Linux重定向前言标准文件描述符重定向输入Redirecting Input重定向输出 Redirecting Output附加重定向输出 Appending Redirected Output重定向标准输出和标准错误 Redirecting Standard Output and Standard Error...

    前言

    本文主要在于总结Linux重定向的问题并分享一些容易发生的错误…

    标准文件描述符Standard File Descriptor

    Linux的标准文件描述符有三个

    文件描述符文字描述
    0标准输入(STDIN)
    1标准输出(STDOUT)
    2标准错误(STDERR)

    重定向输入Redirecting Input

    对于终端来说,shell从STDIN文件描述符对应的键盘获得输入.
    可以使用标准输入重定向符号(<)来指定文件替代键盘输入
    假设一个文本文件words的内容为

    // words
    Linux Jingbo Author Editor
    I LOVE LINUX
    

    这是一个读取文件的shell

    #!/bin/bash
    #display.sh
    filename=$1
    while read word
    do
    	echo "$word"
    done < $filename
    #$1代表的是shell的第二个参数代表文件名
    

    运行这个脚本
    sh ./display.sh words
    输出的内容与word中的内容相同,read 从文本words中读取内容

    重定向输出 Redirecting Output

    有些时候我们可能不想让输出输出到屏幕,而是想让它输出到文件这是就需要重定向输出(>)
    列如

    cat /etc/passwd > file
    

    这样屏幕就不会显示任何输出,任何输出都会输出到file内容当中

    附加重定向输出 Appending Redirected Output

    重定向输出默认会清除掉原文的内容,但有时候可能想要保留源文件的内容这时候可以使用附加重定向输入(>>)
    例如 :

    $ echo "Hello world " >> words
    $ cat words
       Linux Jingbo Author Editor
       I LOVE LINUX
       Hello world
    $
    

    重定向标准输出和标准错误 Redirecting Standard Output and Standard Error

    假如我们想让find的搜索结果定向到find_log这个文件,也许会这样做

    $ find /etc/* > find_log
    

    但是,它并不是那么完美,屏幕仍然输出了find的错误信息(因为普通用户不能查看某些目录,此时会有permission denied 出现),如果我们想全部输出到find_log这个文件里面
    我们需要这样做

    $ find /etc/* > find_log 2>&1
    

    这样屏幕就不会输出任何内容 &1 代表在此代表的是文件描述符1(STDOUT)因为如果不加&这个符号
    shell会认为把标准错误输出到一个文件名为1的文件里面.所以2>&1表示将标准错误定向到标准输出.

    附加标准输出和标准错误 Appending Standard Output and Standard Error

    这个与附加标准输出相似 大概就像这样用

    $ find /etc/* >> find_log 2>&1
    

    Here Documents

    Here Documents 这种类型的重定向指示shell从当前源读取输入,直到看到一个只包含单词的行(没有尾部空白)。然后,所有读到这的行都被用作一个命令的标准输入.
    例如

    $ cat << Hello 
    heredoc> I love Linux
    heredoc> Now we are at $PWD
    heredoc> lalala
    heredoc> Hello
    I love Linux     #这是输出
    Now we are at /home/user
    lalala
    

    如果加有引号,还是例子说明的明白些

    cat << "Hello"
    heredoc> Now we are at $PWD 
    heredoc> Hello
    Now we are at $PWD    #并不会进行替换
    

    如果出现这种形式 <<- shell会忽视掉行首的制表符(并不会忽视空格)
    例如

    $ cat <<- ok
    heredoc>		what  what   #此处为\t 
    heredoc>     waht    #此处为空格
    heredoc>ok
    what what 
         what
    

    Here Strings

    Here Stings 是Here Document 的一种更简洁的变体,由(<<<)表示
    例如可以这样使用

    $ tr a-z A-Z <<<"Yes, I'm a sring"
    YSE,I'M A STRING
    

    复制文件描述符 Duplicating File Descriptors

    这是一个shell脚本

    #!/bin/bash
    exec 3>test  #创建文件描述符
    echo "Hello,world" >&3    #输出到文件描述符
    

    此时将会在 ./下创建test文件,并将Hello,world输出到test中,如果3未被指定,则会发生错误.一般额外的数字可以为(3~9)
    如果我们想让标准输出到test中可以这样做

    #!/bin/bash
    exec 3>&1 #指定3到STDOUT,用来一会儿恢复STDOUT
    exec 1>testfile
    echo "Hello,world" #此时文件会输出到 testfile中
    exec 1>&3 # 恢复标准输出
    echo "Hello,world,monitor" #这个会输出到终端中
    

    你可能会疑问,3 ->1 1-> testfile ,所以文件描述符3不应该也指向testfile,其实文件描述符1的改变并不会影响文件描述符3的改变,所以可以这样来备份恢复STDOUT,如果有需要的话
    另外 可以使用 3>&- 来关闭文件描述符

    移动文件描述符 Moving File Descriptors

    移动文件描述的工作就像是转交工作,这样表示[n]<&digit-
    这里就不举例子了,如果原本存在3>&1 那么 4>&3- 那么&3 的任务 就交给了 &4

    打开文件描述符进行读写 Opening File Descriptors for Reading and Writing

    创建一个文件描述符从一个文件中进行读写,但容易发生意想不到的错误,例子
    假如testfile中又这些内容

    Fir line
    Sec line
    Tir line
    

    这是一个测试脚本

    exec 3<> testfile
    read line <&3
    echo "$line"
    echo"Hello,world" >&3
    

    此时文件终端会输出第一行
    但文件内的内容会像这样

    Fir line
    Hello,world
     line
    

    因为对同一文件进行读写时,会shell会存在一个指针,当用read读取完第一行后,指针会指向第二行的行首,所以输出会输出到第二行,从而覆盖了第二行的内容

    这是对linux重定向的介绍,如果有错误的话,还请大神指正(手动狗头)

    参考文献 :Bash Reference Manual
    Bash Reference Manual

    展开全文
  • Linux 重定向

    2018-10-14 00:13:06
    Linux 重定向介绍> >> 1> 1>> 2> 2>> < <<

    一、重定向符号:> >> 1> 1>> 2> 2>> < <<

    1.标准输出重定向: >与1>
    1.1 >

      [root@NSW ~]# ls
      anaconda-ks.cfg  install.log.syslog
      [root@NSW ~]# echo My name is NSW>nsw.txt      
      [root@NSW ~]# cat nsw.txt 
      My name is NSW
    

    //新建nsw.txt,并将>左边的字符写入到文件中。目录下无文件,自动创建文件。

    1.2 1>
    [root@NSW ~]# echo My name is NSW 1>test.txt
    [root@NSW ~]# cat test.txt
    My name is NSW
    //同理。

    [root@NSW ~]# cat nsw.txt 
      My name is NSW
      [root@NSW ~]# echo I love oldboy >nsw.txt 
      [root@NSW ~]# cat nsw.txt 
      I love oldboy
    

    //可以看出>会将源文件的内容覆盖。(谨慎)

      [root@NSW ~]# echo Welcome 1>nsw.txt 
      [root@NSW ~]# cat nsw.txt 
      Welcome
    

    //1>同样也会先覆盖原文件的内容。

    小结:重定向符>和1>都为输出重定向;
    被输入的文件有则直接输入,无则自动创建该文件并输入;
    将符号左边的字符串输入到右边文件中且覆盖原文件。

    2.追加输出重定向:>> 1>>

       [root@NSW ~]# ls
       anaconda-ks.cfg  install.log.syslog  nsw.txt  test.txt
       [root@NSW ~]# cat nsw.txt 
       Welcome
       [root@NSW ~]# echo My name is nsw>>nsw.txt 
       [root@NSW ~]# cat nsw.txt 
       Welcome
       My name is nsw
    

    //可以看出确实在云文件最后面新追加了My name is nsw没有覆盖源文件。

       [root@NSW ~]# echo My name is nsw1>>nsw.txt 
       [root@NSW ~]# cat nsw.txt 
       Welcome
       My name is nsw
       My name is nsw1
    

    //这需要注意的是符号左面需要空一格要不系统会认为1是输入的字符。

       [root@NSW ~]# echo My name is nsw 1>>nsw.txt 
       [root@NSW ~]# cat nsw.txt 
       Welcome
       My name is nsw
       My name is nsw1
       My name is nsw
    

    //同理1>>和>>作用相同。

       [root@NSW ~]# ls
       anaconda-ks.cfg  install.log.syslog  nsw.txt  test.txt
       [root@NSW ~]# echo Hello >>hello.txt
       [root@NSW ~]# cat hello.txt 
       Hello
       [root@NSW ~]# cat HELLO.txt 
       HELLO
    

    小结:追加输出重定向>>和1>>,将内容追加到指定文件中最后一行的下一行,不会覆盖源文件;
    指定目录下有源文件直接追加,没有则自定创建文件并追加内容。

    3.标准错误重定向2>

       [root@NSW ~]# cat hello.txt 
       Hello
       [root@NSW ~]# eho test
       -bash: eho: command not found
       [root@NSW ~]# eho test 2>hello.txt 
       [root@NSW ~]# cat hello.txt 
       -bash: eho: command not found
    

    //将错误重定向到指定文件中并覆盖原文件内容。

    4.错误追加重定向2>>

        [root@NSW ~]# cat test.txt 
        My name is NSW
        [root@NSW ~]# eho Hello 2>> test.txt 
        [root@NSW ~]# cat test.txt 
        My name is NSW
       -bash: eho: command not found
    

    //将错误追加到指定文件中。

        [root@NSW ~]# ls
        anaconda-ks.cfg  install.log.syslog
        [root@NSW ~]# eho hello 2>test.txt
        [root@NSW ~]# cat test.txt 
        -bash: eho: command not found
        [root@NSW ~]# 
        [root@NSW ~]# 
        [root@NSW ~]# eho hello 2>>test.txt
        [root@NSW ~]# cat test.txt 
       -bash: eho: command not found
       -bash: eho: command not found
    

    //无论2>还是2>>在目录下没有指定文件时都会自动创建文件。

    小结:标准错误输出重定向和错误追加重定向都是将执行错误的提示内容放入指定文件中,故障排查,区别在于一个是覆盖一个是追加。

    5.标准输入重定向:<

       [root@NSW ~]# echo 1 2 3 4 5 6 >test.txt
       [root@NSW ~]# cat test.txt 
       1 2 3 4 5 6
       [root@NSW ~]# xargs -n2 test.txt 
       ^C
       [root@NSW ~]# xargs -n2 <test.txt 
       1 2
       3 4
       5 6
    

    //用来将<右侧文件中的内容输出给左侧的命令,可以使用<符号的命令很少,xargs为其中之一。

    6.追加输入重定向:<<

       [root@NSW ~]# ls
       anaconda-ks.cfg  install.log.syslog  test.txt
       [root@NSW ~]# cat >>nsw.txt<<EOF
       > Hello!
       > My name is NSW
       > EOF
       [root@NSW ~]# cat nsw.txt 
       Hello!
       My name is NSW
    

    //将多行内容追加输入到指定文件中,指定目录下没有文件则新建。

    小结:<是用来将符号右侧文本的内容作为左侧命令的执行条件;
    <<是方便输入多行内容到指定文件中。

    ============================================================
    如果文中有错误的地方欢迎大家指出,谢谢!

    展开全文
  • linux 重定向

    千次阅读 2016-12-07 13:59:32
    LINUX默认输入是键盘,输出是显示器。你可以用重定向来改变这些设置。比如用wc命令的时候本来是要手动输入一篇文字来计算字符数的, 用了重定向后可以直接把一个已经写好的文件用‘<’指向这条命令,就直接可以统计...

    source: http://blog.csdn.net/neubuffer/article/details/16900313


      LINUX默认输入是键盘,输出是显示器。你可以用重定向来改变这些设置。比如用wc命令的时候本来是要手动输入一篇文字来计算字符数的,
    用了重定向后可以直接把一个已经写好的文件用‘<’指向这条命令,就直接可以统计这个文件的字符数等了。输出也是一样,你可以把屏幕输出重
    定向到一个文件里,再到文件里去看结果。 
      重定向操作符可以用来将命令输入和输出数据流从默认位置重定向到其他位置,其输入或输出数据流的位置称为句柄;常见的句柄有三种,当
    然句柄可以自行扩展,一般的OS都提供类似的功能。
    
    句柄句柄代号句柄描述
    STDIN0键盘输入
    STDOUT1输出信息到提示符窗口
    STDERR2输出错误信息到提示符窗口

             默认的 < 重定向输入操作符是 0,而默认的 > 重定向输出操作符是 1。键入 < 或 > 操作符之后,必须指定数据的读写位置,可以是文件名或其他现有的句柄。
    要指定重定向到现有句柄,请使用与 & 字符,后面接要重定向的句柄号(即 &句柄号)。
    例如,下面的命令可以将句柄 2(即 STDERR)重定向到句柄 1(即 STDOUT):2>&1
    下表列出了可用于重定向输入和输出数据流的操作符:

    重定向操作符功能描述
    >将命令输出写入文件或设备,而不是命令提示符或句柄
    <从文件而不是从键盘或句柄读入命令输入
    >>将命令输出添加到文件末尾而不删除文件中已有的信息
    >&将一个句柄的输出写入到另一个句柄的输入中
    <&从一个句柄读取输入并将其写入到另一个句柄输出中
    |从一个命令中读取输出并将其写入另一个命令的输入中;也称为管道操作符

      现在我们回过头来看看上面的那条语句mysh > mylog.txt 2>&1就可明白:

    > mylog.txt意思是将标准输出重定向到mylog.txt,等价于mysh 1> mylog.txt;

    2 >& 1 意思是将错误输出重定向到句柄1标准输出;综合起来就是mysh命令执行过程中产生的标准输出和错误输出都会被重定向到mylog.txt中;

    重定向的功能十分强大,有兴趣的可以去尝试各种不同的组合,看看前后位置变下会有什么结果?

    某些时候我们可能并不希望记录什么标准输出或者是错误输出,那可以用mysh >null 2>null或者mysh >/dev/null 2>/dev/null;

    -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------

     

    I/O重定向详解及应用实例

    1、 基本概念(这是理解后面的知识的前提,请务必理解)

    a、 I/O重定向通常与 FD有关,shell的FD通常为10个,即 0~9;

    b、 常用FD有3个,为0(stdin,标准输入)、1(stdout,标准输出)、2(stderr,标准错误输出),默认与keyboard、monitor、monitor有关;

    c、 用 < 来改变读进的数据信道(stdin),使之从指定的档案读进;

    d、 用 > 来改变送出的数据信道(stdout, stderr),使之输出到指定的档案;

    e、 0 是 < 的默认值,因此 < 与 0<是一样的;同理,> 与 1> 是一样的;

    f、 在IO重定向 中,stdout 与 stderr 的管道会先准备好,才会从 stdin 读进资料;

    g、 管道“|”(pipe line):上一个命令的 stdout 接到下一个命令的 stdin;

    h、 tee 命令是在不影响原本 I/O 的情况下,将 stdout 复制一份到档案去;

    i、 bash(ksh)执行命令的过程:分析命令-变量求值-命令替代(``和$( ))-重定向-通配符展开-确定路径-执行命令;

    j、 ( ) 将 command group 置于 sub-shell 去执行,也称 nested sub-shell,它有一点非常重要的特性是:继承父shell的Standard input, output, and error plus any other open file descriptors。

    k、 exec 命令:常用来替代当前 shell 并重新启动一个 shell,换句话说,并没有启动子 shell。使用这一命令时任何现有环境都将会被清除。exec 在对文件描述符进行操作的时候,也只有在这时,exec 不会覆盖你当前的 shell 环境。

    2、 基本IO

    cmd > file 把 stdout 重定向到 file 文件中;

    cmd >> file 把 stdout 重定向到 file 文件中(追加);

    cmd 1> fiel 把 stdout 重定向到 file 文件中;

    cmd > file 2>&1 把 stdout 和 stderr 一起重定向到 file 文件中;

    cmd 2> file 把 stderr 重定向到 file 文件中;

    cmd 2>> file 把 stderr 重定向到 file 文件中(追加);

    cmd >> file 2>&1 把 stderr 和 stderr 一起重定向到 file 文件中(追加);

    cmd < file >file2 cmd 命令以 file 文件作为 stdin,以 file2 文件作为 stdout;

    cat <>file 以读写的方式打开 file;

    cmd < file cmd 命令以 file 文件作为 stdin;

    cmd << delimiter Here document,从 stdin 中读入,直至遇到 delimiter 分界符。

    3、 进阶IO

    >&n 使用系统调用 dup (2) 复制文件描述符 n 并把结果用作标准输出;

    <&n 标准输入复制自文件描述符 n;

    <&- 关闭标准输入(键盘);

    >&- 关闭标准输出;

    n<&- 表示将 n 号输入关闭;

    n>&- 表示将 n 号输出关闭;

    上述所有形式都可以前导一个数字,此时建立的文件描述符由这个数字指定而不是缺省的 0 或 1。如:

    ... 2>file 运行一个命令并把错误输出(文件描述符 2)定向到 file。

    ... 2>&1 运行一个命令并把它的标准输出和输出合并。(严格的说是通过复制文件描述符 1 来建立文件描述符 2 ,但效果通常是合并了两个流。)

    我 们对 2>&1详细说明一下 :2>&1 也就是 FD2=FD1 ,这里并不是说FD2 的值 等于FD1的值,因为 > 是改变送出的数据信道,也就是说把 FD2 的 “数据输出通道” 改为 FD1 的 “数据输出通道”。如果仅仅这样,这个改变好像没有什么作用,因为 FD2 的默认输出和 FD1的默认输出本来都是 monitor,一样的! 但是,当 FD1 是其他文件,甚至是其他 FD 时,这个就具有特殊的用途了。请大家务必理解这一点。

    exec 0exec 1>outfilename # 打开文件outfilename作为stdout。

    exec 2>errfilename # 打开文件 errfilename作为 stderr。

    exec 0<&- # 关闭 FD0。

    exec 1>&- # 关闭 FD1。

    exec 5>&- # 关闭 FD5。

    问: 如果关闭了 FD0、FD1、FD2,其后果是什么? 恢复 FD0、FD1、FD2与 关闭FD0、FD1、FD2 有什么区别?代码分别是什么? 打开了FD3~FD9,我们用完之后,你觉得是将他们关闭还是恢复?

    下面是提示(例子来源于CU一帖子,忘记出处,来日再补上):

    exec 6>&2 2>ver 
    command >>dev/null & 
    exec 2>&6 # 恢复 FD2

    4、 简单举例

    a、stdout和stderr都通过管道送给egrep了:

    (ls you no 2>&1;ls yes 2>&1) 2>&1|egrep \* >file 
    (ls you no 2>&1;ls yes 2>&1)|egrep \* >file 
    (ls you no;ls yes) 2>&1|egrep \* >file

    这个例子要注意的就是:

    理 解 命令执行顺序 和 管道“|”:在命令执行前,先要进行重定向的处理,并将把 nested sub-shell 的stdout 接到 egrep 命令的 stdin。 nested sub-shell ,在 ( ) 中的两个命令加上(),可以看作一个命令。其 FD1 已经连接到“|”往egrep送了,当遇到 2>&1时,也就是FD2=FD1,即FD2同FD1一样,往管道 “|”那边送。

    b、 没有任何东西通过管道送给egrep,全部送往monitor。 (ls you no 2>&1;ls yes 2>&1) >&2|egrep \* >file。虽然在()里面将 FD2转往FD1,但在()外,遇到 >&2 ,结果所有的都送到monitor。 请理解:

    (ls you no 2>&1) 1>&2|egrep \* >file ## 送到 monitor 
    ls you no 2>&1 1>&2|egrep \* >file ## 送给 管道 “|” 
    ls you no 1>&2 2>&1|egrep \* >file ## 送到 monitor

     

    5、 中阶例子

    条件: stderr通过管道送给egrep,正确消息仍然送给monitor(不变)

    exec 4>&1;(ls you no 2>&1 1>&4 4>&-;ls yes 2>&1 1>
    &4 4>&-)|egrep \* >file;exec 4>&- 
    或者 
    exec 4>&1;(ls you no;ls yes) 2>&1 1>
    &4 4>&-|egrep \* >file;exec 4>&-

    如果加两个条件:

    (1)要求cmd1和cmd2并行运行;

    (2)将cmd1的返回值赋给变量 ss。

    则为:

    exec 3>&1;exec 4>&1 
    ss=$(((ls you no 2>&1 1>&3 3>&-;echo $? >&4)|egrep \* >file) 4>&1) 
    exec 3>&-;exec 4>&-

    说明:

    exec 3>&1;4>&1 建立FD3,是用来将下面ls那条语句(子shell)中的FD1 恢复到正常FD1,即输出到monitor,你可以把FD3看作最初始的FD1的硬盘备份(即输出到monitor);建立FD4,到时用作保存ls的返 回值(echo $?),你可以将FD4看作你考试时用于存放计算“echo $?”的草稿纸;

    (ls you no 2>&1 1>&3 3>&-;echo $? >&4) 大家还记得前面说的子shell和管道吧。这条命令首先会继承FD0、FD1、FD2、FD3、FD4,它位于管道前,所以在运行命令前会先把子 shell自己的FD1和管道“|”相连。但是我们的条件是stderr通过管道送往egrep,stdout仍然输出到monitor。 于是通过2>&1,先把 子shell的FD1 的管道“送给”FD2,于是子shell中的stderr送往管道“|”;再通过 1>&3,把以前的“硬盘备份”恢复给子shell的FD1,于是子shell中的FD1变成送到monitor了。再通过3> &- ,将3关闭;接着运行echo $? ,本来其输出值应该送往管道的,通过 >&4 ,将 输出 送往 “草稿纸”FD4,留以备用。

    ((ls you no 2>&1 1>&3 3>&-;echo $? >&4)|egrep \* >file) 于是,stderr 通过管道送给 egrep ,stdout 送给monitor,但是,还有 FD4,它送到哪去了? $(((ls you no 2>&1 1>&3 3>&-;echo $? >&4)|egrep \* >file) 4>&1)最后的 4>&1 ,就是把FD4 重定向到 FD1。但由于其输出在 $( )中,其值就赋给变量ss了。最后一行关闭 FD3、FD4。 

    6、 高阶例子

    命令 cmd1, cmd2, cmd3, cmd4. 如何利用单向管道完成下列功能:

    1. 所有命令并行执行。

    2. cmd1 和 cmd2 不需要 stdin。

    3. cmd1 和 cmd2 的 stdout 定向到 cmd3 的 stdin。

    4. cmd1 和 cmd2 的 stderr 定向到 cmd4 的 stdin。

    5. cmd3 的 stdout 定向到文件 a, stderr 定向到屏幕。

    6. cmd4 的 stdout 定向到文件 b, stderr 定向到屏幕。

    7. cmd1 的返回码赋给变量 s。

    8. 不能利用临时文件。

    解决方法:

    exec 3>&1; exec 4>&1 
    s=$(((((cmd1 1>&3 ; echo $? >&4 )| cmd2 ) 3>
    &1 | cmd3 >a 2>&3 ) 2>&1 | cmd4 >b ) 4>&1) 
    exec 3>&-; exec 4>&-

    这 个我一步步解释(好复杂,自己感觉看明白了,过一会再看,大脑仍然有几分钟空白~~~,没想到我也能看明白。exec 3>&1; exec 4>&1 前面的例子都有说明了,就是建立FD3 ,给cmd1恢复其FD1用和给cmd3 恢复其FD2用,建立FD4,保存“echo $?”输出值的“草稿纸”。

    第 一对括号:(cmd1 1>&3 ; echo $? >&4 ) 和其后(第一个)管道。在第一个括号(子shell)中,其FD1已经连到 管道中了,所以用 FD3 将 FD1恢复正常,不让他往管道跑;这里的cmd1没有stdin,接着将 cmd1 运行的返回码 保存到 FD4 中。

    第 二对括号:((cmd1 1>&3 ; echo $? >&4 )| cmd2 ) 3>&1 和其后(第二个)管道。前面的 FD1 已经不送给 cmd2了,FD2 默认也不送过来,所以cmd2 也没有stdin ,所以在第二对括号里面:cmd1和cmd2 的stdout、stderr 为默认输出,一直遇到 “3>&1”为止。请注意:“3>&1”,先将第二对括号看出一个命令,他们遇到 第二个管道时,其FD1 连到 管道 “|”,由于“3>&1”的作用,子shell的FD1 送给FD3 使用,所以所有FD3 的输出都 “流往”cmd3,又由于继承关系(继承第一行的命令),FD3实际上就是cmd1和cmd2的stdout,于是“ cmd1 和 cmd2 的 stdout 定向到 cmd3 的 stdin”

    第 三对括号:(((cmd1 1>&3 ; echo $? >&4 )| cmd2 ) 3>&1 | cmd3 >a 2>&3 ) 2>&1 和其后的第三个管道。cmd1 和 cmd2 的 stdout 已经定向到 cmd3 的 stdin,处理之后,cmd3 >a 意味着将其 stdout 送给 a 文件。而2>&3的意思是:恢复cmd3的错误输出为FD3,即送往 monitor。于是“cmd3 的 stdout 定向到文件 a, stderr 定向到屏幕”。如果没有“2>&3”,那么cmd3的错误输出就会干扰cmd1和cmd2的错误输出,所以它是必须的!请注意第三对括号后 的 “2>&1”| ,其子shell的FD1 本来连接着管道“|”,但子shell FD1 慷慨大方,送给了 FD2,于是FD2 连接着管道。还记得前面的 cmd1 和 cmd2 吗?他们的stderr一直没动了。于是在这里,通过管道送给了 第四个命令cmd4 了。即“cmd1 和 cmd2 的 stderr 定向到 cmd4 的 stdin”。后面就比较简单了。cmd4 >b 表示“cmd4 的 stdout 定向到文件 b, stderr 定向到屏幕(默认)”

    第 四对括号:((((cmd1 1>&3 ; echo $? >&4 )| cmd2 ) 3>&1 | cmd3 >a 2>&3 ) 2>&1 | cmd4 >b ) 与其后的 4>&1。四对括号里面的 FD1、FD2都处理完了。但是还记得前面“echo $? >&4”那块“草稿纸”吗?“4>&1”的作用就是“将草稿纸上的内容送给monitor”,但是由于最外面还有 $() 将其“包着”。于是其值赋给变量“s”。


    展开全文
  • Linux重定向管道

    2018-04-05 22:30:20
    Linux重定向是指修改原来默认的一些东西,对原来系统命令的默认执行方式进行改变,比如说简单的我不想看到在显示器的输出而是希望输出到某一文件中就可以通过Linux重定向来进行这项工作。输出重定向的示例://默认...
  • 本篇算是整理学习一下Linux重定向操作符。 常用的是 > 重定向符, 把前面输出的内容重定向到后边指定的位置。例如win系统中: 或者 >> 重定向追加内容到后边的位置,例如: Linux Shel...
  • linux重定向

    2018-03-08 18:36:12
    1.输出重定向的两种方式:&gt; 覆盖原文件内容&gt;&gt; 追加写,不覆盖原文件内容2.两种重定向错误命令重定向 2&gt; 或 2&gt;&gt; (错误命令重定向中 &gt;或和&gt;&gt; ...
  • Linux重定向失败

    千次阅读 2019-01-19 20:02:56
     Linux系统有一个重定向功能,可以将命令的输出重定向输出至文件中。重定向符号有 &gt; 和 &gt;&gt;。&gt;会将目标文件清空,再写入结果;&gt;&gt; 则是追加到文件末尾。  看一个例子:...
  • linux输入重定向、输出重定向
  • linux重定向输出

    2020-11-18 18:09:07
    >表示将标准输出重定向文件,如果是旧文件则覆盖 >>表示将标准输出重定向追加到文件 1>...在类Unix系统中,/dev/null,或称设备,是一个特殊设备,它丢弃一切写入其中的(被称为bit bu.
  • 探究Linux重定向

    2015-10-27 17:18:49
    可能是命令行最酷的特性:I/O 重定向。 ”I/O”代表输入/输出, 通过这个工具,你可以重定向命令的输入输出,命令的输入来自文件,而输出也存到文件。 可以把多个命令连接起来组成一个强大的命令管道。必须掌握...
  • linux重定向详解

    2015-05-14 14:06:05
    理论: 0 一般代表的就是STDIN_FILENO(标准输入) 1 一般代表的就是STDOUT_FILENO(标准输出) 2 一般代表的就是STDERR_FILENO(标准错误) ...实例解释:command >out.file是将command的输出重定向到out

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 48,275
精华内容 19,310
关键字:

linux重定向空

linux 订阅