shell 中的<,<<,>,>>
相信熟悉linux的童鞋不会对这四个符合陌生,shell脚本的文件流有时候真的挺容易搞晕人的,下面我们一起了解一下吧
参考链接:http://www.cnblogs.com/chengmo/archive/2010/10/20/1855805.html
文件描述符
linux启动后,会默认打开3个文件描述符,分别是:标准输入standard input 0,正确输出standard output 1,错误输出:error output 2
以后打开文件后。新增文件绑定描述符 可以依次增加。 一条shell命令执行,都会继承父进程的文件描述符。因此,所有运行的shell命令,都会有默认3个文件描述符。
linux shell下常用输入输出操作符是:
1. 标准输入 (stdin) :代码为 0 ,使用 < 或 << ; /dev/stdin -> /proc/self/fd/0 0代表:/dev/stdin
2. 标准输出 (stdout):代码为 1 ,使用 > 或 >> ; /dev/stdout -> /proc/self/fd/1 1代表:/dev/stdout
3. 标准错误输出(stderr):代码为 2 ,使用 2> 或 2>> ; /dev/stderr -> /proc/self/fd/2 2代表:/dev/stderr
>,>>
输出重定向:表示把将输出重定向到屏幕或者设备或者文件
下面我们直接看一些例子吧
qiweijie@qiweijie:~/study_shell$ ls t.txt t.txt1 ls: 无法访问t.txt1: 没有那个文件或目录 t.txt # 正确输出和错误输出都显示在屏幕上 # 我们试着把正确输出重定向到suc.txt(success),可以看到屏幕输出上只有错误输出了, #从这里也可以看出,默认的正确输出(代码为1,)是可以忽略不写的 qiweijie@qiweijie:~/study_shell$ ls t.txt t.txt1 >suc.txt ls: 无法访问t.txt1: 没有那个文件或目录 qiweijie@qiweijie:~/study_shell$ cat suc.txt t.txt # 正确输出和错误输出分别输出到不同的文件 qiweijie@qiweijie:~/study_shell$ ls t.txt t.txt1 1>suc.txt 2>err.txt qiweijie@qiweijie:~/study_shell$ cat suc.txt err.txt t.txt ls: 无法访问t.txt1: 没有那个文件或目录 # >> 这样写表示追加到文件 qiweijie@qiweijie:~/study_shell$ ls t.txt t.txt1 1>>suc.txt 2>>err.txt qiweijie@qiweijie:~/study_shell$ cat suc.txt err.txt t.txt t.txt ls: 无法访问t.txt1: 没有那个文件或目录 ls: 无法访问t.txt1: 没有那个文件或目录 # &[-,1,2] 分别表示关闭对应的标识,正确输出,错误输出 # 关闭错误输出 qiweijie@qiweijie:~/study_shell$ ls t.txt t.txt1 2>&- t.txt # 错误输出重定向到/dev/null qiweijie@qiweijie:~/study_shell$ ls t.txt t.txt1 2>/dev/null t.txt # 错误输出重定向到到文件 qiweijie@qiweijie:~/study_shell$ ls t.txt t.txt1 2>err1.txt t.txt # 关闭正确输出和错误输出 qiweijie@qiweijie:~/study_shell$ ls t.txt t.txt1 1>&- 2>&- # 都输出到/dev/null qiweijie@qiweijie:~/study_shell$ ls t.txt t.txt1 1>/dev/null 2>/dev/null # 把错误输出重定向到正确输出,正确输出重定向到/dev/null qiweijie@qiweijie:~/study_shell$ ls t.txt t.txt1 1>/dev/null 2>&1 qiweijie@qiweijie:~/study_shell$ ls t.txt t.txt1 >/dev/null 2>&1 qiweijie@qiweijie:~/study_shell$ ls t.txt t.txt1 >ttt.txt 2>&1 qiweijie@qiweijie:~/study_shell$ cat ttt.txt ls: 无法访问t.txt1: 没有那个文件或目录 t.txt # &代表所有输出 qiweijie@qiweijie:~/study_shell$ ls t.txt t.txt1 &>/dev/null qiweijie@qiweijie:~/study_shell$ ls t.txt t.txt1 &>te.txt qiweijie@qiweijie:~/study_shell$ cat te.txt ls: 无法访问t.txt1: 没有那个文件或目录 t.txt
输入重定向<,<<
也是直接来看一些例子吧
# cat命令表示从屏幕获取输入,然后输出 qiweijie@qiweijie:~/study_shell$ cat sadf sadf # 最简单的例子,从屏幕获取输入,然后重定向给qwj(这里用到是的是输出重定向 qiweijie@qiweijie:~/study_shell$ cat > qwj qiweijie shi 2B qiweijie@qiweijie:~/study_shell$ cat qwj qiweijie shi 2B #这里首先是从文件qwj获取输入给cat,然后cat输入重定向给qwj1 qiweijie@qiweijie:~/study_shell$ cat > qwj1 <qwj qiweijie@qiweijie:~/study_shell$ cat qwj1 qiweijie shi 2B # << 两个小于号连在一起表示接受一个输入结束的标识,当输入这个标识是结束输入 qiweijie@qiweijie:~/study_shell$ cat > qq << eof > q > w > j > eof qiweijie@qiweijie:~/study_shell$ cat qq q w j qiweijie@qiweijie:~/study_shell$ cat > qqq << e > q > w > e qiweijie@qiweijie:~/study_shell$ cat qqq q w qiweijie@qiweijie:~/study_shell$
exec绑定重定向
# 绑定新的文件描述符之前的状态 qiweijie@qiweijie:~/study_shell$ ls /proc/self/fd 0 1 2 3 # 绑定一个新的文件描述符6,并且绑定标准输出(相当于给标准输出保存一个临时copy) qiweijie@qiweijie:~/study_shell$ exec 6>&1 qiweijie@qiweijie:~/study_shell$ ls /proc/self/fd 0 1 2 3 6 # 绑定标准输出给suc.txt qiweijie@qiweijie:~/study_shell$ exec 1>suc.txt # 发现标准输出都没有了啊 qiweijie@qiweijie:~/study_shell$ ls -al # 俨然发现suc.txt已经是输出文件 qiweijie@qiweijie:~/study_shell$ cat suc.txt cat: suc.txt:输入文件是输出文件 qiweijie@qiweijie:~/study_shell$ ls /proc/self/fd # 把标准输出绑定回来 qiweijie@qiweijie:~/study_shell$ exec 1>&6 qiweijie@qiweijie:~/study_shell$ ls /proc/self/fd 0 1 2 3 6 # 关闭自定义的文件描述符 qiweijie@qiweijie:~/study_shell$ exec 6>&- qiweijie@qiweijie:~/study_shell$ ls /proc/self/fd 0 1 2 3 qiweijie@qiweijie:~/study_shell$ cat suc.txt 总用量 128 drwxrwxr-x 2 qiweijie qiweijie 4096 11月 24 10:50 . drwxr-xr-x 34 qiweijie qiweijie 4096 11月 24 10:06 .. -rw-rw-r-- 1 qiweijie qiweijie 61 11月 18 14:19 atlga.xml -rw-rw-r-- 1 qiweijie qiweijie 35 11月 18 14:16 atlga.xml.old -rw-rw-r-- 1 qiweijie qiweijie 13 11月 17 16:17 dos-file.txt -rw-rw-r-- 1 qiweijie qiweijie 52 11月 24 10:11 err1.txt -rw-rw-r-- 1 qiweijie qiweijie 104 11月 24 10:09 err.txt -rw-rw-r-- 1 qiweijie qiweijie 41 11月 18 14:20 example.txt -rwxrwxr-x 1 qiweijie qiweijie 94 11月 17 16:56 finduser -rw-rw-r-- 1 qiweijie qiweijie 0 11月 24 10:50 g -rw-rw-r-- 1 qiweijie qiweijie 324 11月 18 14:57 merge-sales.sh -rw-rw-r-- 1 qiweijie qiweijie 271 11月 18 17:08 my-friends -rw-rw-r-- 1 qiweijie qiweijie 140 11月 23 17:43 my-friends.sh -rwxrwxr-x 1 qiweijie qiweijie 141 11月 17 16:34 nusers -rw-rw-r-- 1 qiweijie qiweijie 1958 11月 18 13:54 passwd.txt -rw-rw-r-- 1 qiweijie qiweijie 6 11月 24 10:48 qq -rw-rw-r-- 1 qiweijie qiweijie 4 11月 24 10:49 qqq -rw-rw-r-- 1 qiweijie qiweijie 35 11月 18 14:54 quotas -rw-rw-r-- 1 qiweijie qiweijie 16 11月 24 10:46 qwj -rw-rw-r-- 1 qiweijie qiweijie 16 11月 24 10:47 qwj1 -rw-rw-r-- 1 qiweijie qiweijie 39 11月 18 14:53 sales -rw-rw-r-- 1 qiweijie qiweijie 0 11月 24 11:00 suc.txt -rw-rw-r-- 1 qiweijie qiweijie 58 11月 24 10:40 te.txt -rwxrwxr-x 1 qiweijie qiweijie 55 11月 17 17:02 trace1.sh -rw-rw-r-- 1 qiweijie qiweijie 58 11月 24 10:31 ttt.txt -rw-rw-r-- 1 qiweijie qiweijie 23733 11月 18 15:52 t.txt -rw-rw-r-- 1 qiweijie qiweijie 14 11月 17 16:18 unix-file.txt -rw-rw-r-- 1 qiweijie qiweijie 13 11月 17 16:20 unix.txt -rw-rw-r-- 1 qiweijie qiweijie 25 11月 17 16:15 UN工x-file.txt 0 1 2 3 6 # 如果直接把标准输出绑定到文件,那么问题就是,你再也变不回来了 qiweijie@qiweijie:~/study_shell$ exec 1>suc.txt qiweijie@qiweijie:~/study_shell$ cat suc.txt cat: suc.txt:输入文件是输出文件 qiweijie@qiweijie:~/study_shell$ exec 1>&- qiweijie@qiweijie:~/study_shell$ cat suc.txt cat: 标准输出: 错误的文件描述符 qiweijie@qiweijie:~/study_shell$ ls /proc/self/fd ls: 写入错误: 错误的文件描述符 qiweijie@qiweijie:~/study_shell$
相信通过这些例子,大家对文件描述符和<,<<,>,>>这四个符号应该有一定的印象了吧
如果定界符以任何一种形式的引号括起来, Shell 便不会处理输入的内文:
qiweijie@qiweijie:~/study_shell$ cat << 'e'of
> echo $file
> eof
echo $file
qiweijie@qiweijie:~/study_shell$ cat << eof
> echo $file
> eof
echo nusers
qiweijie@qiweijie:~/study_shell$
以<>打开一个文件作为输入与输出之用
警告<>最初是出现在最早的 V7 Bourne Shell 上,不过并没有形成文档,且经验告诉我们,在
很多环境下,它的运行会有点问题。基于此,它并未被大家广泛了解或使用。虽然它已在
1992 年的 POSIX 标准中标准化,但很多系统里的 /bin/sh 并不支持它。因此如果你对程
序可移植性的要求很高,最好避免使用。
qiweijie@qiweijie:~/study_shell$ (cd test/) ;pwd /home/qiweijie/study_shell qiweijie@qiweijie:~/study_shell$ { cd test/ ;} ;pwd /home/qiweijie/study_shell/test