Shell总结09-IO重定向

Shell总结09-IO重定向

重定向作为unix特有的操作,其操作符是shell默认的内置命令

符号 模式
> 输出重定向覆盖模式
>> 输出重定向追加模式
< 输入重定向覆盖模式
<< 输入重定向追加模式
>& 文件描述符绑定符
<> 读写访问操作符

标准stdin、stdout、stderr

IO重定向通常涉及三个基本的文件描述符stdin、stdout、stderr分别对应描述符数值就是0、1、2。操作系统会为每个进程都建立3个标准输入输出描述符,然后映射到当前字符终端tty类型设备上

[root@localhost ~]# ls /dev/std* -l
lrwxrwxrwx. 1 root root 15 Jul 10 23:45 /dev/stderr -> /proc/self/fd/2
lrwxrwxrwx. 1 root root 15 Jul 10 23:45 /dev/stdin -> /proc/self/fd/0
lrwxrwxrwx. 1 root root 15 Jul 10 23:45 /dev/stdout -> /proc/self/fd/1

[root@localhost ~]# ls -l /proc/self/fd/
lrwx------. 1 root root 64 Jul 10 23:52 0 -> /dev/pts/0
lrwx------. 1 root root 64 Jul 10 23:52 1 -> /dev/pts/0
lrwx------. 1 root root 64 Jul 10 23:52 2 -> /dev/pts/0
lr-x------. 1 root root 64 Jul 10 23:52 3 -> /proc/3584/fd

输出重定向

#标准输出定向到log.txt
ls 1 > log.txt		
ls   > log.txt			#通常标准输出文件描述符1都会省略

#将 标准错误 定向到error.txt
ls 2 > error.txt	

#把 标准输出 和 标准错误 输出重定向到logall.txt文件中
ls &> logall.txt		
ls >& logall.txt		
ls > logall.txt 2>&1
ls > 2>&1 > logall.txt #只会把标准输出1定向到logall.txt中

#把标准输出和标准错误输出重定向到/dev/null文件中-抛弃标准输出和标准错误
ls > /dev/null 2>&1

#重定向操作符的解释顺序为从左到右依次执行重定向操作
#>&是文件描述符绑定标记,比如N>&M执行会创建或更新 符号链接/proc/self/fd/N 到 符号链接/proc/self/fd/M

输入重定向

输入重定向通常用于捕获来自用户或者文件的stdin标准输入

0< FILENAME
 < FILENAME  #表示从文件中获得输入

利用输入重定向实现自动yum自动安装

#!/bin/bash		
# 实现自动yum自动安装
if [ $# -lt 1 ]; then
	echo "Usage: $0 package(s)"
	exit 1
fi

while (($#)); do
	yum install "$1" < CONFIRM
	y
	CONFIRM
shift
done

输入和输出重定向可以组合使用

echo 1234567890 > filea
exec 3<> filea             # 读写模式打开filea,文件描述符为3
read -n 4 <&3             
echo -n . >&3             
exec 3>&-                 
cat filea                  # 1234.67890

exec命令与|pipe管道重定向

exec命令和pipe管道作为重定向的应用通常使用在各种命令组合的场景。

  1. exec

    exec 0 < file   # 将文件重定向到标准输入(0在碰到<时一般省略)
    exec < file
    
    • exec输入重定向
    #!/bin/bash
    
    echo "line1" >> data-file
    echo "line2" >> data-file
    
    exec 6<&0          # 将 标准输入0 和 fd6 绑定,目的是用6保存0的当前状态
    
    exec < data-file   # 将data-file读入标准输入
    
    read a1            # read标准输入0(相当于读data-file首行、第二行)
    read a2            
    
    echo $a1	#line1
    echo $a2	#line2
    
    exec 0<&6 6<&-		#从fd6中还原标准输入0,然后关闭fd6 
    # <&6 6<&-
    read b1			#还原了stdin的read功能
    echo "b1 = $b1"		#键盘输入值
    
    exit 0
    
    • exec输出重定向
    #!/bin/bash
    
    LOGFILE=logfile.txt
    
    exec 6>&1           # 保存stdout到fd6.
    
    exec > $LOGFILE     # 将stdout定向到LOGFILE
    # -----------------开始在LOGFILE中记入内容--------------------- #
    echo -n "Logfile: "
    date
    echo "-------------------------------------"
    echo
    
    echo "Output of "ls -al" command"
    echo
    ls -al
    echo; echo
    echo "Output of "df" command"
    echo
    df
    # -----------------停止在LOGFILE中记入内容--------------------- #
    
    # ----------------------------------------------------------- #
    exec 1>&6 6>&-      # 还原stdout到默认的tty终端设备
    
    echo "== stdout now restored to default == "
    ls -al
    
    exit 0
    
  2. Pipeline管道

    pipeline相比>更有一般性,搭配多个命令使用可以理解为是链式的>

    command1 | command2 | command3 > output-file
    
    cat *.txt | sort | uniq > result-file	#将排序去重结果写入result-file
    
  3. exec与pipeline比较

    find . -type f -name '*.dmg' -exec echo {}.a ;		#有多少个dmg文件exec后命令就执行多少次
    find . -type f -name '*.dmg' -print0 |xargs -0 -I -n1 {} echo {}.a
    
    find . -type f -name '*.dmg' -exec echo {} +		#dmg文件列表作为后续命令的整体参数(效率较高)
    find . -type f -name '*.dmg' -print0 |xargs -0
    
原文地址:https://www.cnblogs.com/elfcafe/p/13269830.html