POSIX标准的输入输出设备:
设备名称 | 文件 | 文件描述符 | 说明 |
---|---|---|---|
标准输入设备 | /dev/stdin | 0 | 键盘 |
标准正确 输出设备 | /dev/stdout | 1 | 显示器 |
标准错误 输出设备 | /dev/stderr | 2 | 显示器 |
空设备 | /dev/null | 相当于垃圾桶 |
在POSIX标准中,一切皆文件,所以,任何设备都对应于操作系统中的一个文件。
在创建进程的时候,会依次打开这个进程的标准输入设备
、标准正确输出设备
、标准错误输出设备
, 所以,他们的文件描述符依次为0
、1
、2
, 后续打开文件的时候根据这个数字自增,关闭文件的时候根据这个数字自减,所以,文件描述符
是动态变化的,而且起到了指针的作用,还可以限制数量。
默认情况下:
标准输入设备
的输入标准正确输出设备
标准错误输出设备
POSIX标准也允许改变这个默认的行为,比如:
输入重定向
就是改变输入的来源。比如:
标准输入设备
输入;标准输入设备
,可是你想换成从普通文件
流入。语法:
COMMAND < FILE
示例:
mysql -uroot -p < xx.sql
mysql命令从xx.sql
文件读入SQL
语句执行。
语法:
COMMAND << delimiter
content
delimiter
delimiter
通常使用EOF
示例:
cat << EOF
Hello
Haha
EOF
cat命令默认是从普通文件读入,这样就可以从标准输入设备
读入了。
语法:
COMMAND <<< STRING
示例:
cat <<< "你好"
cat命令默认是从普通文件读入,这样就可以从字符串
读入了。
输出重定向
的语法格式:
COMMAND N> FILE
COMMAND N>> FILE
N | 说明 |
---|---|
1 | 正确的输出 |
2 | 错误的输出 |
& | 正确的、错误的输出 |
>
是以覆盖
的方式进行输出。
>>
以追加
的方式进行输出。
当N
为1
的时候,可以省略。
示例:
find / -name "*.ttf" 1> ttf.txt
find / -name "*.ttf" > ttf.txt
上面两个命令是等价的。
上面的命令表示:将正确输出
重定向到ttf.txt
文件中, 但是错误输出
没有重定向, 所以,上面的命令一旦发生错误,错误输出
就会显示在屏幕上(标准输出设备
)。
示例:
find / -name "*.ttf" 2> error.txt
上面的命令表示:将错误输出
重定向到error.txt
文件中, 但是正确输出
没有重定向,所以,上面的命令正确执行结果会显示在屏幕上(标准输出设备
), 只有当发生错误的时候,才会把错误结果写进error.txt
文件中。
示例:
find / -name "*.ttf" > ttf.txt 2> error.txt
上面的命令表示:将正确输出
重定向到ttf.txt
文件中; 将错误输出
重定向到error.txt
文件中,这样在执行过程中屏幕上不会显示任何内容。
示例:
find / -name "*.ttf" > ttf.txt 2> ttf.txt
对于这种情况,上面的命令写起来不够简练,其实它可以简化成如下:
find / -name "*.ttf" 2>&1 ttf.txt
更进一步,可以简化成如下:
find / -name "*.ttf" >& ttf.txt
>&
可以换成&>
有时候,我们执行了某个命令,只想使用他的执行结果($?
),不想向用户显示任何信息(正确的、错误的), 这时候,我们通常把这个命令的正确输出
和错误输出
都重定向到/dev/null
这个空设备去。
示例:
command -v curl &> /dev/null || yum install -y curl
在Shell编程中,我们可以把输出的内容重定向到一个变量。使用`
将命令扩起来, 或者使用$()
把命令扩起来,这样就可以把输入重定向到内存中的变量中。
示例:
xx=`ls`
xx=$(ls)
filename=`date +%w`.apk
你经常会看到大片的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命令默认输出到屏幕上(标准输出设备
), 我们给它重定向到普通文件中。