bash输入输出重定向
1.1、输入输出设备

POSIX标准的输入输出设备:

设备名称文件文件描述符说明
标准输入设备/dev/stdin0键盘
标准正确输出设备/dev/stdout1显示器
标准错误输出设备/dev/stderr2显示器
空设备/dev/null相当于垃圾桶

POSIX标准中,一切皆文件,所以,任何设备都对应于操作系统中的一个文件。

在创建进程的时候,会依次打开这个进程的标准输入设备标准正确输出设备标准错误输出设备, 所以,他们的文件描述符依次为012, 后续打开文件的时候根据这个数字自增,关闭文件的时候根据这个数字自减,所以,文件描述符是动态变化的,而且起到了指针的作用,还可以限制数量。

默认情况下:

  • 一个进程的输入接收来自标准输入设备的输入
  • 一个进程的正确输出是输出到标准正确输出设备
  • 一个进程的错误输出是输出到标准错误输出设备

POSIX标准也允许改变这个默认的行为,比如:

  • 输入可以来自任何文件、管道。
  • 也可以输出到任何文件、管道。
1.2、输入重定向

输入重定向就是改变输入的来源。比如:

  • 本来要求输入的来源是普通文件,可是你想换成从标准输入设备输入;
  • 本来要求输入的来源是标准输入设备,可是你想换成从普通文件流入。
1.2.1、从文件流入

语法:

COMMAND < FILE

示例:

mysql -uroot -p < xx.sql

mysql命令从xx.sql文件读入SQL语句执行。

1.2.2、从标准输入读入

语法:

COMMAND << delimiter
content
delimiter

delimiter通常使用EOF

示例:

cat << EOF
Hello
Haha
EOF

cat命令默认是从普通文件读入,这样就可以从标准输入设备读入了。

1.2.3、从字符串读入

语法:

COMMAND <<< STRING

示例:

cat <<< "你好"

cat命令默认是从普通文件读入,这样就可以从字符串读入了。

注意:该语法只有bashzshkshpdksh支持。

1.3、输出重定向

输出重定向的语法格式:

COMMAND N> FILE
COMMAND N>> FILE
N说明
1正确的输出
2错误的输出
&正确的、错误的输出

>是以覆盖的方式进行输出。

>>追加的方式进行输出。

N1的时候,可以省略。

1.3.1、只将正确输出重定向到文件中

示例:

find / -name "*.ttf" 1> ttf.txt
find / -name "*.ttf"  > ttf.txt

上面两个命令是等价的。

上面的命令表示:将正确输出重定向到ttf.txt文件中, 但是错误输出没有重定向, 所以,上面的命令一旦发生错误,错误输出就会显示在屏幕上(标准输出设备)。

1.3.2、只将错误输出重定向到文件中

示例:

find / -name "*.ttf" 2> error.txt

上面的命令表示:将错误输出重定向到error.txt文件中, 但是正确输出没有重定向,所以,上面的命令正确执行结果会显示在屏幕上(标准输出设备), 只有当发生错误的时候,才会把错误结果写进error.txt文件中。

1.3.3、将正确输出和错误输出都重定向到文件中

示例:

find / -name "*.ttf" > ttf.txt 2> error.txt

上面的命令表示:将正确输出重定向到ttf.txt文件中; 将错误输出重定向到error.txt文件中,这样在执行过程中屏幕上不会显示任何内容。

1.3.4、将正确输出和错误输出都重定向到同一个文件中

示例:

find / -name "*.ttf" > ttf.txt 2> ttf.txt

对于这种情况,上面的命令写起来不够简练,其实它可以简化成如下:

find / -name "*.ttf" 2>&1 ttf.txt

更进一步,可以简化成如下:

find / -name "*.ttf" >& ttf.txt

>&可以换成&>

1.3.5、将输出扔到垃圾桶

有时候,我们执行了某个命令,只想使用他的执行结果($?),不想向用户显示任何信息(正确的、错误的), 这时候,我们通常把这个命令的正确输出错误输出都重定向到/dev/null这个空设备去。

示例:

command -v curl &> /dev/null || yum install -y curl
1.3.6、输出重定向到变量

Shell编程中,我们可以把输出的内容重定向到一个变量。使用`将命令扩起来, 或者使用$()把命令扩起来,这样就可以把输入重定向到内存中的变量中。

示例:

xx=`ls`
xx=$(ls)
filename=`date +%w`.apk
1.4、输入重定向和输出重定向相结合的示例

你经常会看到大片的echo命令的输出,比如如下的代码:

echo "deb http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse" >> /etc/apt/sources.list
echo "deb http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse" >> /etc/apt/sources.list
echo "deb http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse" >> /etc/apt/sources.list
echo "deb http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse" >> /etc/apt/sources.list
echo "deb http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse" >> /etc/apt/sources.list

这样看起来很愚蠢,因为它多次打开和关闭同一个文件,而且看起来重复代码也很多,不够简洁,实际上, 利用输入重定向输出重定向相结合就可以完美解决此问题,如下:

cat >> /etc/apt/sources.list <<EOF
deb http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse
EOF

cat命令默认是从普通文件读入, 我们给它重定向到从标准输入设备读入了。

cat命令默认输出到屏幕上(标准输出设备), 我们给它重定向到普通文件中。