当前位置:   article > 正文

重定向与管道符_管道符与重定向

管道符与重定向

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

重定向

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

  • 形式
  • 标准输入
    代码为 0 ,使用<<<
  • 标准输出
    代码为 1 ,使用 >1>>>
  • 标准错误输出
    代码为 2 ,使用 2>2>>

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

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

将会将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
  • 1

输出:

dup(2)   - duplicate a file descriptor
  • 1

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

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

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


----------


 ls -l  link.sh unknow.sh  1>& test
-
 cat test                          
ls: 无法访问'unknow.sh': 没有那个文件或目录
-rwxr-xr-x 1 sss sss 153 520 15:57 link.sh
-
 ls -l  link.sh unknow.sh  2>& test
-rwxr-xr-x 1 sss sss 153 520 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 520 15:57 link.sh
-
 ls -l  link.sh unknow.sh  2&> test
-rwxr-xr-x 1 sss sss 153 520 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 520 15:57 link.sh
-rw-r--r-- 1 sss sss   1 520 20:10 test
-
 cat test                          

#上方有一空行,代表确实全都没有重定向,就不在人为清空test了
-
ls -l  link.sh unknow.sh  >&2 test
ls: 无法访问'unknow.sh': 没有那个文件或目录
-rwxr-xr-x 1 sss sss 153 520 15:57 link.sh
-rw-r--r-- 1 sss sss 114 520 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 520 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 520 15:57 link.sh
#额...貌似test也作为参数了?

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97

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

符号行为
>& 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
  • 1

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
  • 1

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

cat > catfile << "eof"
  • 1

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

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

echo "./"|ls
  • 1

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

  • 管线命令仅会处理 standard output,对于 standard error output 会予以忽略
  • 管线命令必须要能够接受来自前一个指令的数据成为 standard input 继续处理才行
    这下就知道前面2>&1可以干啥了吧,可以让错误信息强制被管道符所用

比较

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

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

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

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/211975
推荐阅读
相关标签
  

闽ICP备14008679号