zoukankan      html  css  js  c++  java
  • 使用exec

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

    使用exec重定向stdin

    1 #!/bin/bash
    2 # 使用'exec'重定向stdin. 
    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 >filename命令将会把stdout重定向到一个指定的文件中. 这样所有命令的输出就都会发送到那个指定的文件, 而不是stdout.

    exec N > filename会影响整个脚本或当前shell. 对于这个指定PID的脚本或shell来说,从这句命令执行之后, 就会重定向到这个文件中, 然而 . . .N > filename只会影响新fork出来的进程, 而不会影响整个脚本或shell. 

    使用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中读取. 
    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
  • 相关阅读:
    BeyondLinux_Since1991
    TED系列:我们究竟在教AI学习什么
    TED系列:算法的影响
    TED系列:代码-下一代的通用语言
    TED系列:互联网源起故事
    Hadoop-01 搭建hadoop伪分布式运行环境
    JavaSE-26 Swing
    JavaSE-25 AWT
    JavaSE-24 多线程
    JavaSE-23 注解
  • 原文地址:https://www.cnblogs.com/fly-xiang-zhao/p/4018959.html
Copyright © 2011-2022 走看看