CentOS下输入输出重定向

  nux重定向是指修改原来默认的一些东西,对原来系统命令的默认执行方式进行改变,比如说简单的我不想看到在显示器的输出而是希望输出到某一文件中就可以通过Linux重定向来进行这项工作。

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

  STDIN 0 键盘输入

  STDOUT 1 输出信息到提示符窗口

  STDERR 2 输出错误信息到提示符窗口

  默认的 < 重定向输入操作符是 0,而默认的 > 重定向输出操作符是 1。键入 < 或 > 操作符之后,必须指定数据的读写位置,可以是文件名或其他现有的句柄。

  要指定重定向到现有句柄,请使用与 & 字符,后面接要重定向的句柄号(即 &句柄号)。

例如,下面的命令可以将句柄 2(即 STDERR)重定向到句柄 1(即 STDOUT):2>&1

  下表列出了可用于重定向输入和输出数据流的操作符:

  Linux重定向操作符 功能描述

  > 将命令输出写入文件或设备,而不是命令提示符或句柄

  < 从文件而不是从键盘或句柄读入命令输入

  >> 将命令输出添加到文件末尾而不删除文件中已有的信息

  >& 将一个句柄的输出写入到另一个句柄的输入中

  <& 从一个句柄读取输入并将其写入到另一个句柄输出中

  | 从一个命令中读取输出并将其写入另一个命令的输入中;也称为管道操作符

  现在我们回过头来看看上面的那条语句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。

[plain] view plaincopy

  1. 1    COMMAND_OUTPUT >
  2. 2       # 重定向stdout到一个文件.
  3. 3       # 如果没有这个文件就创建, 否则就覆盖.
  4. 4
  5. 5       ls -lR > dir-tree.list
  6. 6       # 创建一个包含目录树列表的文件.
  7. 7
  8. 8    : > filename
  9. 9       # > 会把文件"filename"截断为0长度.
  10. 10       # 如果文件不存在, 那么就创建一个0长度的文件(与‘touch‘的效果相同).
  11. 11       # : 是一个占位符, 不产生任何输出.
  12. 12
  13. 13    > filename
  14. 14       # > 会把文件"filename"截断为0长度.
  15. 15       # 如果文件不存在, 那么就创建一个0长度的文件(与‘touch‘的效果相同).
  16. 16       # (与上边的": >"效果相同, 但是在某些shell下可能不能工作.)
  17. 17
  18. 18    COMMAND_OUTPUT >>
  19. 19       # 重定向stdout到一个文件.
  20. 20       # 如果文件不存在, 那么就创建它, 如果存在, 那么就追加到文件后边.
  21. 21
  22. 22
  23. 23       # 单行重定向命令(只会影响它们所在的行):
  24. 24       # --------------------------------------------------------------------
  25. 25
  26. 26    1>filename
  27. 27       # 重定向stdout到文件"filename".
  28. 28    1>>filename
  29. 29       # 重定向并追加stdout到文件"filename".
  30. 30    2>filename
  31. 31       # 重定向stderr到文件"filename".
  32. 32    2>>filename
  33. 33       # 重定向并追加stderr到文件"filename".
  34. 34    &>filename
  35. 35       # 将stdout和stderr都重定向到文件"filename".
  36. 36
  37. 37       #==============================================================================
  38. 38       # 重定向stdout, 一次一行.
  39. 39       LOGFILE=script.log
  40. 40
  41. 41       echo "This statement is sent to the log file, \"$LOGFILE\"." 1>$LOGFILE
  42. 42       echo "This statement is appended to \"$LOGFILE\"." 1>>$LOGFILE
  43. 43       echo "This statement is also appended to \"$LOGFILE\"." 1>>$LOGFILE
  44. 44       echo "This statement is echoed to stdout, and will not appear in \"$LOGFILE\"."
  45. 45       # 每行过后, 这些重定向命令会自动"reset".
  46. 46
  47. 47
  48. 48
  49. 49       # 重定向stderr, 一次一行.
  50. 50       ERRORFILE=script.errors
  51. 51
  52. 52       bad_command1 2>$ERRORFILE       #  错误消息发到$ERRORFILE中.
  53. 53       bad_command2 2>>$ERRORFILE      #  错误消息添加到$ERRORFILE中.
  54. 54       bad_command3                    #  错误消息echo到stderr,
  55. 55                                       #+ 并且不出现在$ERRORFILE中.
  56. 56       # 每行过后, 这些重定向命令也会自动"reset".
  57. 57       #==============================================================================
  58. 58
  59. 59
  60. 60
  61. 61    2>&1
  62. 62       # 重定向stderr到stdout.
  63. 63       # 得到的错误消息与stdout一样, 发送到一个地方.
  64. 64
  65. 65    i>&j
  66. 66       # 重定向文件描述符i 到 j.
  67. 67       # 指向i文件的所有输出都发送到j中去.
  68. 68
  69. 69    >&j
  70. 70       # 默认的, 重定向文件描述符1(stdout)到 j.
  71. 71       # 所有传递到stdout的输出都送到j中去.
  72. 72
  73. 73    0< FILENAME
  74. 74     < FILENAME
  75. 75       # 从文件中接受输入.
  76. 76       # 与">"是成对命令, 并且通常都是结合使用.
  77. 77       #
  78. 78       # grep search-word <filename
  79. 79
  80. 80
  81. 81    [j]<>filename
  82. 82       # 为了读写"filename", 把文件"filename"打开, 并且分配文件描述符"j"给它.
  83. 83       # 如果文件"filename"不存在, 那么就创建它.
  84. 84       # 如果文件描述符"j"没指定, 那默认是fd 0, stdin.
  85. 85       #
  86. 86       # 这种应用通常是为了写到一个文件中指定的地方.
  87. 87       echo 1234567890 > File    # 写字符串到"File".
  88. 88       exec 3<> File             # 打开"File"并且给它分配fd 3.
  89. 89       read -n 4 <&3             # 只读4个字符.
  90. 90       echo -n . >&3             # 写一个小数点.
  91. 91       exec 3>&-                 # 关闭fd 3.
  92. 92       cat File                  # ==> 1234.67890
  93. 93       # 随机存储.
  94. 94
  95. 95
  96. 96
  97. 97    |
  98. 98       # 管道.
  99. 99       # 通用目的的处理和命令链工具.
  100. 100       # 与">"很相似, 但是实际上更通用.
  101. 101       # 对于想将命令, 脚本, 文件和程序串连起来的时候很有用.
  102. 102       cat *.txt | sort | uniq > result-file
  103. 103       # 对所有的.txt文件的输出进行排序, 并且删除重复行,
  104. 104       # 最后将结果保存到"result-file"中.

可以将输入输出重定向和(或)管道的多个实例结合到一起写在一行上.

[html] view plaincopy

  1. 1 command < input-file > output-file
  2. 2
  3. 3 command1 | command2 | command3 > output-file

可以将多个输出流重定向到一个文件上.

[plain] view plaincopy

  1. 1 ls -yz >> command.log 2>&1
  2. 2 #  将错误选项"yz"的结果放到文件"command.log"中.
  3. 3 #  因为stderr被重定向到这个文件中,
  4. 4 #+ 所有的错误消息也就都指向那里了.
  5. 5
  6. 6 #  注意, 下边这个例子就不会给出相同的结果.
  7. 7 ls -yz 2>&1 >> command.log
  8. 8 #  输出一个错误消息, 但是并不写到文件中.
  9. 9
  10. 10 #  如果将stdout和stderr都重定向,
  11. 11 #+ 命令的顺序会有些不同.

exec <filename 命令会将stdin重定向到文件中. 从这句开始, 后边的输入就都来自于这个文件了, 而不是标准输入了(通常都是键盘输入). 这样就提供了一种按行读取文件的方法, 并且可以使用sed 和/或 awk来对每一行进行分析.

使用exec重定向标准输入

1 #!/bin/bash
   2 # 使用‘exec‘重定向标准输入.
   3
   4
   5 exec 6<&0          # 将文件描述符#6与stdin链接起来.
   6                    # 保存了stdin.
   7
   8 exec < data-file   # stdin被文件"data-file"所代替.
   9
  10 read a1            # 读取文件"data-file"的第一行.
  11 read a2            # 读取文件"data-file"的第二行.
  12
  13 echo
  14 echo "Following lines read from file."
  15 echo "-------------------------------"
  16 echo $a1
  17 echo $a2
  18
  19 echo; echo; echo
  20
  21 exec 0<&6 6<&-
  22 #  现在将stdin从fd #6中恢复, 因为刚才我们把stdin重定向到#6了,
  23 #+ 然后关闭fd #6 ( 6<&- ), 好让这个描述符继续被其他进程所使用.
  24 #
  25 # <&6 6<&-    这么做也可以.
  26
  27 echo -n "Enter data  "
  28 read b1  # 现在"read"已经恢复正常了, 就是从stdin中读取.
  29 echo "Input read from stdin."
  30 echo "----------------------"
  31 echo "b1 = $b1"
  32
  33 echo
  34
  35 exit 0

使用exec来重定向stdout

1 #!/bin/bash
   2 # reassign-stdout.sh
   3
   4 LOGFILE=logfile.txt
   5
   6 exec 6>&1           # 将fd #6与stdout相连接.
   7                     # 保存stdout.
   8
   9 exec > $LOGFILE     # stdout就被文件"logfile.txt"所代替了.
  10
  11 # ----------------------------------------------------------- #
  12 # 在这块中所有命令的输出就都发向文件 $LOGFILE.
  13
  14 echo -n "Logfile: "
  15 date
  16 echo "-------------------------------------"
  17 echo
  18
  19 echo "Output of \"ls -al\" command"
  20 echo
  21 ls -al
  22 echo; echo
  23 echo "Output of \"df\" command"
  24 echo
  25 df
  26
  27 # ----------------------------------------------------------- #
  28
  29 exec 1>&6 6>&-      # 恢复stdout, 然后关闭文件描述符#6.
  30
  31 echo
  32 echo "== stdout now restored to default == "
  33 echo
  34 ls -al
  35 echo
  36
  37 exit 0


 使用exec在同一脚本中重定向stdin和stdout

1 #!/bin/bash
   2 # upperconv.sh
   3 # 将一个指定的输入文件转换为大写.
   4
   5 E_FILE_ACCESS=70
   6 E_WRONG_ARGS=71
   7
   8 if [ ! -r "$1" ]     # 判断指定的输入文件是否可读?
   9 then
  10   echo "Can‘t read from input file!"
  11   echo "Usage: $0 input-file output-file"
  12   exit $E_FILE_ACCESS
  13 fi                   #  即使输入文件($1)没被指定
  14                      #+ 也还是会以相同的错误退出(为什么?).
  15
  16 if [ -z "$2" ]
  17 then
  18   echo "Need to specify output file."
  19   echo "Usage: $0 input-file output-file"
  20   exit $E_WRONG_ARGS
  21 fi
  22
  23
  24 exec 4<&0
  25 exec < $1            # 将会从输入文件中读取.
  26
  27 exec 7>&1
  28 exec > $2            # 将写到输出文件中.
  29                      # 假设输出文件是可写的(添加检查?).
  30
  31 # -----------------------------------------------
  32     cat - | tr a-z A-Z   # 转换为大写.
  33 #   ^^^^^                # 从stdin中读取.Reads from stdin.
  34 #           ^^^^^^^^^^   # 写到stdout上.
  35 # 然而, stdin和stdout都被重定向了.
  36 # -----------------------------------------------
  37
  38 exec 1>&7 7>&-       # 恢复 stout.
  39 exec 0<&4 4<&-       # 恢复 stdin.
  40
  41 # 恢复之后, 下边这行代码将会如期望的一样打印到stdout上.
  42 echo "File \"$1\" written to \"$2\" as uppercase conversion."
  43
  44 exit 0

I/O重定向是一种避免可怕的子shell中不可存取变量问题的方法.


避免子shell

1 #!/bin/bash
   2 # avoid-subshell.sh
   3 # Matthew Walker提出的建议.
   4
   5 Lines=0
   6
   7 echo
   8
   9 cat myfile.txt | while read line;  #  (译者注: 管道会产生子shell)
  10                  do {
  11                    echo $line
  12                    (( Lines++ ));  #  增加这个变量的值
  13                                    #+ 但是外部循环却不能存取.
  14                                    #  子shell问题.
  15                  }
  16                  done
  17
  18 echo "Number of lines read = $Lines"     # 0
  19                                          # 错误!
  20
  21 echo "------------------------"
  22
  23
  24 exec 3<> myfile.txt
  25 while read line <&3
  26 do {
  27   echo "$line"
  28   (( Lines++ ));                   #  增加这个变量的值
  29                                    #+ 现在外部循环就可以存取了.
  30                                    #  没有子shell, 现在就没问题了.
  31 }
  32 done
  33 exec 3>&-
  34
  35 echo "Number of lines read = $Lines"     # 8
  36
  37 echo
  38
  39 exit 0
  40
  41 # 下边这些行是脚本的结果, 脚本是不会走到这里的.
  42
  43 $ cat myfile.txt
  44
  45 Line 1.
  46 Line 2.
  47 Line 3.
  48 Line 4.
  49 Line 5.
  50 Line 6.
  51 Line 7.
  52 Line 8.
时间: 2024-10-11 21:27:03

CentOS下输入输出重定向的相关文章

[shell]shell输入输出重定向

Unix 命令默认从标准输入设备(stdin)获取输入,将结果输出到标准输出设备(stdout)显示.一般情况下,标准输入设备就是键盘,标准输出设备就是终端,即显示器. 一般情况下,每个 Unix/Linux 命令运行时都会打开三个文件: 标准输入文件(stdin):stdin的文件描述符为0,Unix程序默认从stdin读取数据. 标准输出文件(stdout):stdout 的文件描述符为1,Unix程序默认向stdout输出数据. 标准错误文件(stderr):stderr的文件描述符为2,

shell介绍、历史命令、命令补全和别名、通配符、输入输出重定向

shell介绍 shell是系统跟计算机硬件交互时使用的中间介质,它只是系统的一个工具.实际上,在shell和计算机硬件之间还有一层东西--系统内核. 用户直接面对的不是计算机硬件而是shell,用户把指令告诉shell,然后shell再传输给系统内核,接着内核再去支配计算机硬件去执行各种操作. Redhat.Centos 默认安装的shell版本是bash,它是sh的增强版. 历史命令 我们执行过的命令Linux都会记录,预设可以记录1000条历史命令.这些命令保存在用户家目录的.bash_h

Linux centos7 shell 介绍、 命令历史、命令补全和别名、通配符、输入输出重定向

一.shell介绍 shell脚本是日常Linux系统管理工作中必不可少的,不会shell,就不是一个合格管理员. shell是系统跟计算机硬件交互使用的中间介质,一个系统工具.实际上在shell和计算机硬件之间还有一层--系统内核.如果吧计算机比作人的躯体,那系统内核就是人的大脑,至于shell,把它比做人的五官更贴切. 其实,用户直接面对的不是计算机硬件而是shell,用户把指令告诉shell,然后shell再传给系统内核,接着内核再去支配计算机硬件去执行各种操作. CentOS安装的she

shell介绍 命令历史 命令补全和别名 输入输出重定向

shell介绍 shell是一个命令解释器,提供用户与机器之间的交互例如我们远程登录的工具,它其实就是一个shell centos默认的shell是bash(Bourne Agin Shell)· 命令历史 history命令命令历史存在用户家目录下的.bash_history,如root用户就是/root/.bash_history·history可以查看命令历史,.bash_history文件了里最多可以存1000条,它是由环境变量HISTSIZE决定的,不过history有时候也会查看到超

shell特性、通配符、输入输出重定向,命令历史

一:shell介绍 shell是一个命令解释器,提供用户和机器之间的交互,支持特定语法,每个用户都可以有自己特定的shell,centos默认为bash,还有zsh,ksh等. 二:命令历史 history命令环境变量HISTSIZE,在/etc/profle中,可以设置修改环境变量数值,修改最大保存数量.改完需要source一下.保存历史命令的时间:HISTTIMEFORMAT="%Y/%m/%d %H:%M:%S"历史命令保存在家目录下.bash_history文件中,最多存100

输入输出重定向及管道

Linux运维之路 基础篇:Linux基础命令(二) 输入输出重定向及管道 标准输入:用0表示(键盘) 标准输出:用1表示(监视器) 标准错误输出:用2表示(监视器) IO重定向:改变标准位置 标准输出重定向: >:覆盖重定向,目标文件原有的内容会被清除(set -C:禁止对已有文件进行覆盖重定 向) (>|:强制进行覆盖重定向) >>:追加重定向,目标文件原有的内容会被保留,新内容追加至结尾 标准错误输出重定向: 2>:标准错误输出覆盖重定向 2>>:标准错误输

8.1 shell 介绍、8.2 命令历史、8.3 命令补全与别名、8.4 通配符、8.5 输入输出重定向

8.1 sehll 介绍 什么是shell shell 是一个命令解释器,提供用户和机器之间交互 支持特定的语法,比如逻辑判断,循环. 每个用户都可以有自己特定的shell. centos7 默认的shell 为bash( Bourne Agin shell ) 还有zsh ,ksh等 8.2 命令历史 /root/.bash_history ;命令历史放置文件 [[email protected] ~]# ls /root/.bash_history/root/.bash_history [[

8.1 shell介绍 8.2 命令历史 8.3 命令补全和别名 8.4 通配符 8.5 输入输出重定向

8.1 shell介绍 8.2 命令历史 8.3 命令补全和别名 8.4 通配符 8.5 输入输出重定向 # Linux shell 基础 # 8.1 shell 介绍 - 什么是shell 1. shell 是一个命令解释器,提供用户和机器之间的交互 2. 支持特定语法,比如逻辑判断.循环 3. 每个用户都可以有自己特定的shell 4. CentOS7 默认shell 为bash (Bourne Agin Shell) 5. 还有zsh.ksh等 ``` [[email protected]

3_Shell语言———输入输出重定向和管道概述

一.输入重定向和输出重定向 通常计算机的I/O(输入/输出)设备为键盘和显示器,因此当我们执行cat命令而不加任何参数时,命令会等待用户通过键盘输入数据:而当我们为cat命令增加了参数/etc/rc.d/rc.sysinit后,cat命令的输入源变成了文件/etc/rc.d/rc.sysinit.这个过程就是输入重定向.如果cat的结果不显示在屏幕中,而是输出到某个文件中,其过程就是输出重定向. 二.管道 管道事实上是一种重定向的过程.管道的一方是数据的输入端,一方是接收端.bash也支持管道,