linux重定向的理解,linux下输入输出重定向

By admin in 美高梅手机版4858 on 2019年4月3日

管道符”|”

管道符”|”:前3个指令的出口,作为后1个指令的输入

命令1 | 命令2 | 命令3 | ...

# 输出"hello,world."并将小写转换为大写
[root@localhost ~]# echo "hello,world." | tr 'a-z' 'A-Z'
HELLO,WORLD.

# 显示passwd文件中按:分割的每行第一个部分并排序并将小写转换为大写
[root@localhost ~]# cut -d: -f1 /etc/passwd | sort | tr 'a-z' 'A-Z'
ADM
APACHE
BIN
DAEMON
DBUS
FEDORA

管道符”|”

管道符”|”:前2个命令的出口,作为后三个命令的输入

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

# 输出”hello,world.”并将小写转换为题写
[root@localhost ~]#美高梅手机版4858 , echo “hello,world.” | tr ‘a-z’ ‘A-Z’
HELLO,WORLD.

# 展现passwd文件中按:分割的每行第3个部分并排序并将小写转换为题写
[root@localhost ~]# cut -d: -f1 /etc/passwd | sort | tr ‘a-z’ ‘A-Z’
ADM
APACHE
BIN
DAEMON
DBUS
Fedora

linux重定向

inux重定向是指修改原来默许的一部分东西,对原来系统命令的暗许执市价势展开转移,比如说简单的本人不想见见在显示屏的出口而是期待输出到某一文书中就能够通过Linux重定一向举行那项工作。

I/O重定向

简短的分解正是捕捉多少个文书, 命令, 程序, 脚本,
恐怕甚至是本子中的代码块的输出, 然后将这个输出作为输入发送到另多个文书,
命令, 程序, 或脚本中。

I/O重定向

简言之的诠释正是捕捉3个文件, 命令, 程序, 脚本,
大概甚至是本子中的代码块的出口, 然后将那么些输出作为输入发送到另1个文本,
命令, 程序, 或脚本中。

 

  Linux暗许输入是键盘,输出是显示屏。你能够用重定一贯改变那一个设置。比如用wc命令的时候自然是要手动输入壹篇文字来测算字符数的,用了重定向后方可间接把三个早已写好的文书用‘<’指向那条命令,就径直能够计算这一个文件的字符数等了。输出也是均等,你可以把显示屏输出重定向到1个文件里,再到文件里去看结果。重定向操作符能够用来将下令输入和输出数据流从私下认可地方重定向到任何职分,其输入或输出数据流的职责称为句柄;常见的句柄有三种,当然句柄能够自行扩大,壹般的OS都提供类似的法力。句柄
句柄代号 句柄描述

专业输入输出

实施二个shell命令行时常常会自动打开八个标准文件,即行业内部输入文件(stdin),平日对应终端的键盘;标准输出文件(stdout)和行业内部错误输出文件(stderr),那多少个文件都对应终端的显示屏。
进度将从专业输入文件中取得输入数据,将常规输出数据输出到正规输出文件,而将错误消息送到正规错误文件中。
习惯上,标准输入(standard input)的文件讲述符是 0,标准输出(standard
output)是 1,标准错误(standard error)是 二。

规范输入输出

实践2个shell命令行时一般会自动打开多少个标准文件,即规范输入文件(stdin),常常对应终端的键盘;标准输出文件(stdout)和标准错误输出文件(stderr),那五个文本都对应终端的显示器。
进度将从规范输入文件中取得输入数据,将符合规律输出数据输出到正式输出文件,而将错误新闻送到标准错误文件中。
见怪不怪上,标准输入(standard input)的文本讲述符是 0,标准输出(standard
output)是 1,标准错误(standard error)是 2。

目录

  STDIN 0 键盘输入

I/O重定向符号

  • cmd 一 | cmd 二 把 stdout 重定向到 cmd 二 的 shdin;
  • cmd > file 把 stdout 也许 stderr 重定向到 file 文件中;
  • cmd >> file 把 stdout 只怕 stderr 重定向到 file 文件中(追加);
  • linux重定向的理解,linux下输入输出重定向。cmd > file 二>&一 把 stdout 和 stderr 1起重定向到 file 文件中;
  • cmd >> file 二>&1 把 stdout 和 stderr 壹起重定向到 file
    文件中(追加);
  • cmd < file >file2 cmd 命令以 file 文件作为 stdin,以 file2文件作为 stdout;
  • cat <>file 以读写的点子打开 file;
  • cmd < file cmd 命令以 file 文件作为 stdin;
  • cmd << delimiter Here document,从 stdin 中读入,直至遇到delimiter 分界符;
  • cmd 一 | cmd 二 > file 把多个 stdout 重定向到 file 文件中。

其间2>&第11中学的数字代表重定向文件描述符,表示重定向 stderr 到 stdout 。

I/O重定向符号

  • cmd 一 | cmd 2 把 stdout 重定向到 cmd 二 的 shdin;
  • cmd > file 把 stdout 大概 stderr 重定向到 file 文件中;
  • cmd >> file 把 stdout 或许 stderr 重定向到 file 文件中(追加);
  • cmd > file 贰>&一 把 stdout 和 stderr 一起重定向到 file 文件中;
  • cmd >> file 贰>&一 把 stdout 和 stderr 壹起重定向到 file
    文件中(追加);
  • cmd < file >file二 cmd 命令以 file 文件作为 stdin,以 file二文件作为 stdout;
  • cat <>file 以读写的措施打开 file;
  • cmd < file cmd 命令以 file 文件作为 stdin;
  • cmd << delimiter Here document,从 stdin 中读入,直至遭逢delimiter 分界符;
  • cmd 一 | cmd 2 > file 把多少个 stdout 重定向到 file 文件中。

里面贰>&第11中学的数字代表重定向文件描述符,表示重定向 stderr 到 stdout 。

 

  STDOUT 壹 输出音信到升迁符窗口

关门文件讲述符

n<&-
#关闭输入文件描述符n.

0<&-
<&-
#关闭stdin.

n>&-
#关闭输出文件描述符n.

1>&-
>&-
#关闭stdout.

关闭文件讲述符

n<&-
#关门输入文件讲述符n.

0<&-
<&-
#关闭stdin.

n>&-
#关闭输出文件讲述符n.

1>&-
>&-
#关闭stdout.

基本概念

  STDEGL450Escort 二 输出错误音讯到升迁符窗口

set

set -C:禁止对已经存在文件使用覆盖重定向:
    强制覆盖输出,则使用 >|
set +C:关闭上述功能

set

set -C:禁止对曾经存在文件使用覆盖重定向:
    强制覆盖输出,则利用 >|
set +C:关闭上述作用

Linux公社的RSS地址:

本文永久更新链接地址

美高梅手机版4858 1

基本IO

  暗中认可的 < 重定向输入操作符是 0,而默许的 > 重定向输出操作符是
一。键入 < 或 >
操作符之后,必须钦命数量的读写地方,能够是文本名或任何现有的句柄。

进阶IO

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

 

比如,下边包车型地铁下令可以将句柄 二(即 STDE大切诺基LAND)重定向到句柄 壹(即
STDOUT):二>&一

基本概念

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

  (那是掌握前面包车型客车知识的前提,请务必明白)

  Linux重定向操作符 作用描述

  a、 I/O重定向平日与 FD有关,shell的FD日常为11个,即 0~玖;

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

  b、
常用FD有一个,为0(stdin,标准输入)、一(stdout,标准输出)、二(stderr,标准错误输出),暗中同意与keyboard、monitor有关;

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

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

  >> 将指令输出添加到文件末尾而不删除文件中已部分消息

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

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

  e、 0 是 < 的暗中认可值,因此 < 与 0<是同等的;同理,> 与
1> 是平等的;

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

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

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

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

  今后我们回过头来看看上面的这条语句mysh > mylog.txt
二>&一就可分晓:

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

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

  i、
bash(ksh)执行命令的长河:分析命令-变量求值-命令替代(“和$(
))-重定向-通配符展开-明显路径-执行命令;

  2 >& 一趣味是将错误输出重定向到句柄一正经输出;综合起来便是mysh命令执行进程中生出的正式输出和谬误输出都会被重定向到mylog.txt中;

  j、 ( ) 将 command group 置于 sub-shell 去履行,也称 nested
sub-shell,它有少数12分主要的特色是:继承父shell的Standard input,
output, and error plus any other open file descriptors。

  重定向的意义卓殊强大,有趣味的能够去尝试各个区别的构成,看看前后地点变下会有何结果?

  k、 exec 命令:常用来替代当前 shell 并再一次启航一个shell,换句话说,并未运维子
shell。使用那壹限令时别的现有条件都将会被解决。exec
在对文件讲述符举办操作的时候,也只有在那时候,exec 不会覆盖你近日的 shell
环境。

  某个时候大家大概并不指望记录什么正儿八经输出或许是一无所能输出,那能够用mysh
>null 二>null或然mysh >/dev/null 二>/dev/null;

 

  I/O重定向详解

基本IO

  1、 基本概念(那是知情后边的学识的前提,请务必领会)

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

  a、 I/O重定向经常与 FD有关,shell的FD平日为13个,即 0~玖;

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

  b、
常用FD有叁个,为0(stdin,标准输入)、一(stdout,标准输出)、二(stderr,标准错误输出),暗中认可与keyboard、monitor、monitor有关;

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

  c、 用 < 来改变读进的多少信道(stdin),使之从钦定的档案读进;

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

  d、 用 > 来改变送出的多寡信道(stdout,
stderr),使之输出到钦点的档案;

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

  e、 0 是 < 的默许值,因而 < 与 0<是均等的;同理,> 与
1> 是相同的;

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

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

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

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

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

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

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

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

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

  j、 ( ) 将 command group 置于 sub-shell 去实施,也称 nested
sub-shell,它有一些相当关键的风味是:继承父shell的Standard input,
output, and error plus any other open file descriptors。

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

  k、 exec 命令:常用来代替当前 shell 并再次起动一个shell,换句话说,并不曾运维子
shell。使用这一指令时其余现有条件都将会被免除。exec
在对文本讲述符举办操作的时候,也唯有在那儿,exec 不会覆盖你近来的 shell
环境。

 

  2、 基本IO

进阶IO

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

 

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

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

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

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

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

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

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

  >&- 关闭标准输出;

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

  n<&- 表示将 n 号输加入关贸总协定组织闭;

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

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

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

  上述全数方式都足以指点二个数字,此时确立的公文讲述符由这么些数字钦定而不是缺省的
0 或 一。如:

  cat <>file 以读写的法子打开 file;

  … 2>file 运营叁个发令并把错误输出(文件讲述符 贰)定向到 file。

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

  … 二>&一运维一个命令并把它的正经输出和出口合并。(严峻的乃是通过复制文件讲述符 1来确立文件讲述符 二 ,但成效平常是联合了四个流。)

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

  笔者 们对 2>&一详细说澳优(Ausnutria Hyproca)(Karicare)下 :二>&一 也正是 FD二=FD一,那里并不是说FD二 的值 等于FD一的值,因为 >
是改变送出的数据信道,也等于说把 FD二 的 “数据输出通道” 改为 FD1 的
“数据输出通道”。如若仅仅那样,那些改变好像未有怎么效果,因为 FD2的暗中认可输出和 FD一的默许输出本来都以 monitor,1样的! 可是,当 FD一是任何文件,甚至是别的 FD
时,那么些就有着特种的用途了。请大家必须领悟那或多或少。

  3、 进阶IO

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

  >&n 使用系统调用 dup (贰) 复制文件讲述符 n 并把结果用作专业输出;

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

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

  exec 0<&- # 关闭 FD0。

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

  exec 1>&- # 关闭 FD1。

  >&- 关闭标准输出;

  exec 5>&- # 关闭 FD5。

  n<&- 表示将 n 号输加入关贸总协定协会闭;

 

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

 

  上述全体方式都足以引导2个数字,此时创建的文书讲述符由那些数字钦赐而不是缺省的
0 或 壹。如:

 

  … 二>file 运营贰个指令并把错误输出(文件讲述符 贰)定向到 file。

作者 ZHB_McCoy

  … 贰>&一运转2个指令并把它的科鲁班出和出口合并。(严厉的身为通过复制文件讲述符 一来建立文件讲述符 二 ,但效益1般是统一了七个流。)

目录 基本概念 基本IO 进阶IO 基本概念
(那是理解前面包车型大巴文化的前提,请务必理解) a、 I/O重定向经常与
FD有关,shell的FD常常为…

  大家对 二>&1详细说圣元(Nutrilon)(Aptamil)下 :二>&一 也等于 FD二=FD一,那里并不是说FD二 的值 等于FD1的值,因为 >
是改变送出的数据信道,也等于说把 FD二 的 “数据输出通道” 改为 FD一 的
“数据输出通道”。假设仅仅那样,这些改变好像未有怎么功用,因为 FD2的暗中同意输出和 FD一的暗中同意输出本来都以 monitor,1样的!但是,当 FD①是其余文件,甚至是其余 FD
时,这些就有着特种的用处了。请大家必须了然那或多或少。

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

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

  exec 0<&- # 关闭 FD0。

  exec 1>&- # 关闭 FD1。

  exec 5>&- # 关闭 FD5。

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

能够将输入输出重定向和(或)管道的三个实例结合到3只写在一行上.

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

能够将多少个出口流重定向到二个文件上.

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

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图
Copyright @ 2010-2019 美高梅手机版4858 版权所有