Shell 输入/输出重定向
Unix/Linux系统每个命令运行时都会打开三个文件:
- 标准输入设备(stdin):stdin文件描述符为0,默认从stdin读取数据。
- 标准输出设备(stdout):stdout 文件描述符为1,默认向stdout输出数据。
- 标准错误设备(stderr):stderr文件描述符为2,默认向stderr写入错误信息。
终端命令模式下标准输入/输出设备就你的终端屏幕。
输入/输出重定向指的是将输入/输出设备指向非标准设备,如文件等
重定向方式如下:
方式 | 说明 |
---|---|
command > file | 将命令输出重定向到文件(覆盖式),如:echo 'abc' > a.txt |
command >> file | 将命令输出重定向到文件,但是以内容追加方式 |
command < file | 将命令输入重定向到文件 |
n > file | 将文件描述符为 n 的文件重定向到 file。 |
n >> file | 将文件描述符为 n 的文件以追加的方式重定向到 file。 |
n >& m | 将输出文件 m 和 n 合并。 |
n <& m | 将输入文件 m 和 n 合并。 |
<< tag | 将开始标记 tag 和结束标记 tag 之间的内容作为输入,常用于交互式脚本输入 |
输出重定向示例:
执行下面的 who 命令,它将命令的完整的输出重定向在用户文件中(users):
# 将命令echo结果输出到a.txt文件,如果文件不存在则新建
$ echo "new out chars" > a.txt
# 将命令ps结果输出追加到a.txt
$ ps -ef|grep java >> a.txt
$ cat a.txt
new out chars
oper 311 1 0 8月01 ? 00:02:42 /usr/local/jdk1.8/bin/java -server -Xms386m -Xmx786m -jar biz.jar
oper 312 1 0 8月01 ? 00:03:26 /usr/local/jdk1.8/bin/java -server -Xms386m -Xmx786m -jar mch.jar
oper 431 1 0 8月01 ? 00:02:57 /usr/local/jdk1.8/bin/java -server -Xms386m -Xmx786m -jar admin.jar
命令执行后并没有在终端输出信息,这是因为输出已被从默认的标准输出设备重定向到指定的文件。
将命令错误输出重定向到文件:command 2>file
[oper@test96 ~]$ wc -a c.txt
wc:无效选项 -- a
Try 'wc --help' for more information.
[oper@test96 ~]$ wc -a 2>c.txt
[oper@test96 ~]$ cat c.txt
wc:无效选项 -- a
Try 'wc --help' for more information.
将 stderr和 stdout 合并后重定向到 file
command > file 2>&1
记忆提示:先理解1是标准输出,2个标准错误输出,&是合并的意思,2>&1可以读作2大与1
输入重定向示例:
统计文件行数
[oper@test96 ~]$ wc -l b.txt
14 b.txt
[oper@test96 ~]$ wc -l < b.txt
14
注意:上面两个例子的结果不同:第一个命令,会输出文件名,第二个不会,因为文件内容被重定向到了标准输入,命令读取内容是从标准输入读取所以没有文件名
同时重定向输入和输出
command1 < infile > outfile
执行command1,从文件infile读取内容,然后将内容写入到outfile中
如果希望将 stdout 和 stderr 合并后重定向到file,可以这样写:
$ command > file 2>&1
或者
$ command >> file 2>&1
java程序后台启动命令示例:
nohup java -jar xx.jar >> out.log 2>&1 &
输入重定向到交互式shell 脚本或程序, 如脚本中需要执行sudo命令时,因为sudo命令是需要输入密码的,此时就可以利用该重定向方式实现提前输入密码。
它的命令形式如下:
command << delimiter
document
delimiter
将两个 delimiter 之间的内容作为输入传递给 command,delimiter通用使用EOF符号.
示例:
sudo -S sh xxx.sh <<EOF
>password
>EOF
shell脚本进入mysql client 并执行sql语句
#!/bin/bash
#连接mysql数据库,并查询结果,将结果输出到文件中
mysql_u="root"
mysql_p="123123"
result_file="/home/result.sql"
echo "开始链接数据库..."
result=`mysql -u$mysql_u -p$mysql_p<< EOF
use db1;
select * from user where a='b';
quit
EOF`
if [ $? = 0 ]
then
echo "连接成功。。。"
else
echo "连接失败。。。"
exit
fi
echo "写入查询结果..."
echo "$result" > $result_file
echo "写入完成..."
/dev/null 文件
/dev/null 是一个特殊的空设备文件,写入到它的内容都会被丢弃, 因此将命令输出重定向到/dev/null相当于忽略任何输出
$ command > /dev/null
$ command > /dev/null 2>&1
利用/dev/null清空文件内容:
cat /dev/null > access.log