adinxu
by adinxu
2 分钟 阅读用时

分类

标签

重定向与管道符

重定向与管道是两个神奇的东西…我现在还没搞懂他们…慢慢来

重定向

下面是三种是我最早见到的,然后,我又见到了一些理解不能的语句,后来又发现其他形式的重定向…晕乎乎

>1>相同,>代表了默认是重定向标准输出
1>: 以覆盖的方法将『正确的数据』输出到指定的文件或装置上;
1>>: 以累加的方法将『正确的数据』输出到指定的文件或装置上;
2>: 以覆盖的方法将『错误的数据』输出到指定的文件或装置上;
2>>: 以累加的方法将『错误的数据』输出到指定的文件或装置上;
总之两个代表追加…
下面这句

find /home -name .bashrc > list_right 2> list_error

将会将find执行结果保存,其中标准输出保存到list_right,错误输出保存到list_error,这两个文件:
若不存在则创建
若存在则覆盖


摘自百度知道:
linux重定向中&>>&是一个意思,是“复制一个文件描述符”的意思。
标准输入(stdin) 代码为 0 ,实际映射关系:/dev/stdin -> /proc/self/fd/0
标准输出(stdout)代码为 1 , 实际映射关系:/dev/stdout -> /proc/self/fd/1
标准错误输出(stderr)代码为 2 ,实际映射关系: /dev/stderr ->/pro/self/fd/2

原先有一句关于管道和重定向区别的话,是说重定向的作用对象只能是文件(这里我想吐槽一下,不是说linux一切皆文件吗…),看到上面说的映射关系,我大概能了解一点了,现在学习的主要问题就是不了解底层,只知道表面肯定会晕…就像for循环,c里面说for(expr1;expr2;expr3)这里第一个填初始化式子,第二个填控制条件,第三个控制循环,但我如果说,第一个就是开始时运行,第二个为真继续循环,第三个每次都会执行,那么我写程序的选择就很多了…
然后,接着说:

>< 分别代表重定向的方向,是从左到右还是从右到左
>><<代表追加,也就是不改变重定向目标文件原有的内容,追加在后面
>&n 使用系统调用 dup (2) 复制文件描述符 n 并把结果用作标准输出;
<&n 标准输入复制自文件描述符 n;

上述dup(2)我猜是这个:
终端:

man -f dup

输出:

dup(2)   - duplicate a file descriptor

2代表种类:系统核心可呼叫的函数与工具等
实验时间…
目录下有一脚本link.sh,不存在unknow.sh
运行命令(-是我手动添加的,代表一次执行及输出,注释也是后加的):

ls -l  link.sh unknow.sh &> test
-
cat test                        
ls: 无法访问'unknow.sh': 没有那个文件或目录
-rwxr-xr-x 1 sss sss 153 5月  20 15:57 link.sh
-
ls -l  link.sh unknow.sh >& test
-
cat test                        
ls: 无法访问'unknow.sh': 没有那个文件或目录
-rwxr-xr-x 1 sss sss 153 5月  20 15:57 link.sh

#这里&>和>&是一样的,标准和错误输出全部重定向了


----------


 ls -l  link.sh unknow.sh  1>& test
-
 cat test                          
ls: 无法访问'unknow.sh': 没有那个文件或目录
-rwxr-xr-x 1 sss sss 153 5月  20 15:57 link.sh
-
 ls -l  link.sh unknow.sh  2>& test
-rwxr-xr-x 1 sss sss 153 5月  20 15:57 link.sh
-
cat test                          
ls: 无法访问'unknow.sh'ls: 无法访问'unknow.sh': 没有那个文件或目录
: 没有那个文件或目录

#这里可以看到,1>&与前同,而2>&并没有将标准输出重定向到test,
#只把错误输出重定向到了test,而且还重复了一句...


----------


ls -l  link.sh unknow.sh  1&> test
-
 cat test
ls: 无法访问'unknow.sh': 没有那个文件或目录
-rwxr-xr-x 1 sss sss 153 5月  20 15:57 link.sh
-
 ls -l  link.sh unknow.sh  2&> test
-rwxr-xr-x 1 sss sss 153 5月  20 15:57 link.sh
-
cat test
ls: 无法访问'unknow.sh'ls: 无法访问'unknow.sh': 没有那个文件或目录
: 没有那个文件或目录
#这里还是一样,1&>与前同,而2&>同样并没有将标准输出重定向到test,只把错误输出重定向到了test,同样重复了一句


----------


echo "">test #清空test消除干扰,测试一下,应该是多余担心了..
-
cat test

-
ls -l  link.sh unknow.sh  >&1 test
ls: 无法访问'unknow.sh': 没有那个文件或目录
-rwxr-xr-x 1 sss sss 153 5月  20 15:57 link.sh
-rw-r--r-- 1 sss sss   1 5月  20 20:10 test
-
 cat test                          

#上方有一空行,代表确实全都没有重定向,就不在人为清空test了
-
ls -l  link.sh unknow.sh  >&2 test
ls: 无法访问'unknow.sh': 没有那个文件或目录
-rwxr-xr-x 1 sss sss 153 5月  20 15:57 link.sh
-rw-r--r-- 1 sss sss 114 5月  20 19:59 test

#这里可以看出,这样写重定向完全没起作用..
#即>&1 >&2,其实这里test被直接执行了...,也就是说>&1和>&2就是两个标准输出本身
----------
 ls -l  link.sh unknow.sh  &>1 test
 #这里没有任何输出,test也没有,但多了一个文件1,全都到1里去了
-
ls -l  link.sh unknow.sh  &>2 test
#同上,没输出,都到2里去了


----------
ls -l  link.sh unknow.sh  1>&2 test
ls: 无法访问'unknow.sh': 没有那个文件或目录
ls: 无法访问'test': 没有那个文件或目录
-rwxr-xr-x 1 sss sss 153 5月  20 15:57 link.sh
-
 ls -l  link.sh unknow.sh  2>&1 test
ls: 无法访问'unknow.sh': 没有那个文件或目录
ls: 无法访问'test': 没有那个文件或目录
-rwxr-xr-x 1 sss sss 153 5月  20 15:57 link.sh
#额...貌似test也作为参数了?


搞个表格,空行代表与上方相邻不为空的相同
输出重定向:

符号 行为

|——

`>& file` 重定向标准输出和错误输出 `&> file` `1>& file` `1&> file` `2>& file` 重定向了标准错误输出,但是有问题,会出现重复两次的现象,这个还没搞懂 `2&> file`

特殊情况:

符号 行为

|——

`>&1` 到标准输出 `>&2` 到标准错误输出 `1>&2` 将标准输出转成标准错误输出 `2>&1` 将标准错误输出转成标准输出

按照前面说的

>&n 使用系统调用 dup (2) 复制文件描述符 n 并把结果用作标准输出;

我觉得输出重定位应该这样理解,>&&>是相同的,但代表标准输出的1和代表标准错误输出的2只应该在其左边,也就是开口方向,不然就不算重定向了.
好烦…以后就只需要记住全部重定向输出用>&&>好了,少打一个字…
可以直接记>&好了,形式比较一致

**最终:**

符号 行为

|——

`>` 标准输出重定向 `2>` 标准错误输出重定向 `>&` 标准输出与标准错误输出全部重定向 `>&1` 标准输出 `>&2` 标准错误输出 `1>&2` 将标准输出转成标准错误输出 `2>&1` 将标准错误输出转成标准输出

追加

符号 行为

|——

`>>` 追加标准输出重定向 `2>>` 追加标准错误输出重定向 `>>&` 追加标准输出与标准错误输出全部重定向

另外,不能同时用>和2>同时输出到同一文件,会乱码的…

至于输入,这句没搞懂啥意思

<&n 标准输入复制自文件描述符 n;

然后还有这个,也看不懂,以后再说吧…:

n<&- 表示将 n 号输入关闭
<&-表示关闭标准输入(键盘)
n>&-表示将 n 号输出关闭
>&- 表示将标准输出关闭

下面是式子:

cat > testfile

man cat得:

cat - concatenate files and print on the standard output

cat是将文件输出到屏幕,而当未指定文件时:

With no FILE, or when FILE is -, read standard input

它会去读标准输入,也就是键盘输入
那么上面的就是将键盘输入的打印到屏幕,但因为后面接了重定向,于是输入的内容会跑到文件里去.
下一句:

cat > catfile < ~/.bashrc

上面说了当cat参数未指定,那么会去读标准输入,这时候~/.bashrc就会变为标准输入了,结果catfile里存的是 ~/.bashrc的内容.执行顺序,cat等待标准输入,catfile等待重定向的标准输出,这时候.bashrc作为标准输入进入,然后cat拿到给了输出,重定向到了catfile,好绕…
下一句

cat > catfile << "eof"

右边<<“eof”代表不改变源文件内容,追加eof,这个我只能猜一猜了…
前面是一样的,后面代表最后输入的一定是eof,所以输了eof就能直接结束了,换其他字符也一样
管道

前面说了重定向,这里要说管道符了,我对这两个比较模糊,
比如下面这个命令:

echo "./"|ls

可以列出当前目录内容,管道符具有以下特点:

比较

  1. 管道符和重定向有什么区别?
    看下面两个命令,其输出是一样的 ``` cat < link.sh cat link.sh|cat

```

来张图:
重定向
结合一下这两句话:

&gt;&amp;n 使用系统调用 dup (2) 复制文件描述符 n 并把结果用作标准输出;
&lt;&amp;n 标准输入复制自文件描述符 n;

额,大概就是这样吧,所以说输入输出重定向就是取代了键盘屏幕,能够接受键盘输入的都可以用重定向改为文件输入,能够输出到屏幕的,都可以通过重定向保存到文件.
而管道符可以把标准输出转标准输入,以让可以接受标准输入的命令可以以此为输入执行命令,所以说,重定向也可以做到同样的事情,但一般来说不会这么做,就像cat,默认以文件名为参数,没有文件名才从标准输入读,