详细理解:
linux命令默认从标准输入设备(stdin)获取输入,将结果输出到标准输出设备(stdout)显示。一般情况下,标准输入设备就是键盘,标准输出设备就是终端,即显示器。在linux shell执行命令时,每个进程都和三个打开的文件相联系,并使用文件描述符来引用这些文件。由于文件描述符不容易记忆,shell同时也给出了相应的文件名:
文件描述符说明列表
文件 | 文件描述符 |
---|---|
输入文件-标准输入 | 0(缺省为键盘;0为文件或其他命令的输出) |
输出文件-标准输出 | 1(缺省为屏幕;1为文件) |
错误输出文件-标准错误 | 2(缺省为屏幕;2为文件) |
全部可用的命令行列表
命令 | 说明 |
---|---|
command > file | 将输出重定向到 file。 |
command < file | 将输入重定向到 file。 |
command >> file | 将输出以追加的方式重定向到 file。 |
n > file | 将文件描述符为 n 的文件重定向到 file。 |
n >> file | 将文件描述符为 n 的文件以追加的方式重定向到 file。 |
n >& m | 将输出文件 m 和 n 合并。 |
n <& m | 将输入文件 m 和 n 合并。 |
<< tag | 将开始标记 tag 和结束标记 tag 之间的内容作为输入。 |
默认情况下,command > file 将stdout重定向到file,command < file 将stdin重定向到file。
- 如果希望stderr重定向到 file,可以这样写:
$ command 2 > file # 2表示标准错误文件(stderr)
- 如果希望stderr追加到file文件末尾,可以这样写:
$ command 2 >> file # >>表示追加写入,不覆盖之前的内容
- 如果希望将stdout和stderr合并后重定向到file,可以这样写:
$ command > file 2>&1
或
$ command >> file 2>&1
- 如果希望对stdin和stdout 都重定向,可以这样写:
$ command < infile > outfile # command命令将stdin重定向到infile,将stdout重定向到outfile
有个空设备的文件的重定向输出,如果想屏蔽stdout,stderr,则:
$ ping a.b.c > /dev/null 2>&1
输出重定向:
linux命令的输出可以是,默认是屏幕
- 屏幕显示器
- 文件
比如说,执行who这个命令,如果不重定向到文件的话,在屏幕下会回显:
$ who
user1 tty01 Jan 12 01:30
user2 tty02 Jan 12 02:30
user3 tty03 Jan 12 03:30
user4 tty04 Jan 12 04:30
user5 tty05 Jan 12 05:30
但如果执行的是下面的命令,那么who命令执行的结果,只能用cat,more或less在users文件里查看了。
$ who > users
如果在刚才的users文件里面执行下面的内容,则users的内容就被覆盖了:
$ echo "Line 1" > users
Line 1
$
如果不想被覆盖,就必须用:>>
$ echo "Line 2" >> users
Line 1
Line 2
$
输入重定向:
- 例1: 拿刚才的users文件,要统计其行数
$ wc -l < users
2
$
- 例2: 将文件file1内容发送给test@163.com,邮件标题为: Email Test
mail -s "mail test" test@163.com < file1
- 例3: 拿刚才users文件内容进行大小写转换,然后重新输出到 > users2
$ tr 'a-z' 'A-Z' < users > users2
LINE 1
LINE 2
- 例4: 用bc命令来计算cal.txt输入中的内容
$ echo 1+2 > cal.txt
$ bc < cal.txt
3
$
- 例5: 用sort命令来对输入文件排序,排序后重定向到输出文件
$ cat fruits_in
tomato
strawberry
pear
apple
cherry
$ sort < fruits_in > fruits_out
$ cat fruits_out
apple
cherry
pear
strawberry
tomato
Here Document:
Here Document:是Shell中的一种特殊的重定向方式,它的基本的形式如下:
command << delimiter
document
delimiter
它的作用是将两个delimiter之间的内容(document) 作为输入传递给command. 最主要的用途:用于脚本命令行交互中。下面会举例子:
NOTE:
- 开始的delimiter前后的空格会被忽略掉.
- 结尾的delimiter一定要顶格写,前面不能有任何字符,后面也不能有任何字符,包括空格和tab缩进
- delimiter可以使任何tag,只要满足上面两个条件
- Here Document可用于命令行中,或脚本里面
举例如下:
- 例子1: 用wc -l命令计算document的行数
$wc -l << EOF
This is line 1
This is line 2
This is line 3
EOF
3
$
- 例子2: 用cat命令将here docuemnt读取出来
$ touch test1.sh
$ chmod +x ./test1.sh
#!/bin/bash
cat << TAG
aaaaaaaaaaaaaa
bbbbbbbbbbbbbb
cccccccccccccc
TAG
$ ./test1.sh
aaaaaaaaaaaaaa
bbbbbbbbbbbbbb
cccccccccccccc
- 例子3:用vi命令,在脚本里面,将编辑的内容写入文件中
$ touch test2.sh
$ chmod +x ./test2.sh
#!/bin/bash
filename=test.txt
ed $filename << delimiter
This is line 1
This is line 2
This is line 3
.
wq
delimiter
$ ./test2.sh
$ cat test.txt
This is line 1
This is line 2
This is line 3
$
- 例子4:用here document在脚本中实现对Mysql数据的操作;
$ mysql -u root -p password
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 1257
Server version: 5.1.35-community MySQL Community Server (GPL)
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> use mysql
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
mysql> select * from user;
mysql> exit
Bye
要在脚本中实现上面的命令行交互方式,可以用here document在shell中实现
#!/bin/sh
mysql -u root -p password << EOF_MYSQL
use mysql
select * from user;
exit
EOF_MYSQL