Linux shell管道与重定向及实例分析

一、管道

管道命令操作符是:"|",它仅能处理由前面一个命令的正确输出信息,也就是standard output的信息,对于stdandard error信息没有直接处理能力;然后,传递给下一个命令,作为标准输入standard input。

linux管道执行过程:

管道命令使用说明:

command1正确输出,作为command2的输入,然后command2的输出作为command3的输入,command3的输出打印到屏幕上;

通过管道:command1、command2的正确输出不会显示在屏幕上。

注意:

1、管道命令只处理前一个命令的正确输出,不处理错误输出;

2、管道命令右边的命令,必须能够接收标准输入流命令。

实例:

例1:

cat test.sh | grep -n ‘echo‘

3:   echo "nice";

5:   echo "good";

7:   echo "pass";

9:   echo "shit";

# 读取test.sh文件内容,通过管道转发给grep作为输入内容

例2:

cat test.sh test1.sh | grep -n ‘echo‘

cat: test1.sh: 没有那个文件或目录

3:   echo "nice";

5:   echo "good";

7:   echo "pass";

9:   echo "shit";

# test1.sh不存在,错误输出打印到屏幕,正确输出通过管道发送给grep

例3:

cat test.sh test1.sh 2>/dev/null | grep -n ‘echo‘

3:   echo "nice";

5:   echo "good";

7:   echo "pass";

9:   echo "shit";

# 将错误输出重定向输出给/dev/null文件,正确输出通过管道发送给grep

例4:

cat test.sh | ls

test.sh test1.sh test2.sh

# 读取test.sh内容,通过管道发送给ls命令,由于ls不支持标准输入,因此数据被丢弃

二、重定向

linux文件描述符:

可以理解为linux跟踪打开文件,而分配的一个数字,这个数字有点类似C语言操作文件时候的句柄,通过句柄就可以实现文件的读写操作;用户可以自定义文件描述符范围:3-num,这个最大数字,跟用户的ulimit -n定义数字有关系,不能超过最大值。

linux启动后,会默认打开3个文件描述符,分别是:

标准输入:standard input 0;

正确输出:standard output 1;

错误输出:error output 2;

打开文件后,新增文件绑定描述符可以依次增加;一条shell命令执行,会继承父进程的文件描述符。因此,所有运行的shell命令,都会有默认的3个文件描述符。

Linux命令执行过程:

命令执行过程:

先有一个输入:输入可以从键盘,也可以从文件得到;

命令执行完成:执行成功,会把结果输出到屏幕:standard output默认是屏幕;

命令执行有错误:会把错误也输出到屏幕上面:standard error默认也是指的屏幕;

文件输入输出由追踪为一个给定的进程所有打开文件的整数句柄来完成,这些数字值就是文件描述符。众所周知的文件描述符是 stdin, stdout 和 stderr,文件描述符的数字分别是0、1和2,这些数字和各自的设备是保留的。一个命令执行前,先会准备好所有输入输出,默认分别绑定(stdin,stdout,stderr),如果这个时候出现错误,命令将终止,不会执行。

这些默认的输入、输出都是linux系统内定的,我们在使用过程中,有时候并不希望执行结果输出到屏幕,需要输出到文件或其它设备,这个时候就需要进行输出重定向了。

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

输出重定向:

实例:

例1:

# 把错误输出,不输出到屏幕,输出到err.txt

ls test.sh test1.sh 1>suc.txt 2>err.txt

cat suc.txt err.txt

test.sh

ls: test1.sh: 没有这个文件和目录

# 继续追加把输出写入suc.txt err.txt  “>>”追加操作符

ls test.sh test1.sh 1>>suc.txt 2>>err.txt

例2:

# 将错误输出信息关闭掉

ls test.sh test1.sh 2>&-

test.sh

ls test.sh test1.sh 2>/dev/null

test.sh

# &[n] 代表是已经存在的文件描述符

# &1 代表输出

# &2 代表错误输出

# &- 代表关闭与它绑定的描述符

# /dev/null代表linux中的黑洞设备

例3:

# 关闭所有输出

ls test.sh test1.sh 1>&- 2>&-

# 关闭1,2 文件描述符

ls test.sh test1.sh  2>/dev/null 1>/dev/null

# 将1,2 输出转发给/dev/null设备

ls test.sh test1.sh >/dev/null 2>&1

# 将错误输出2 绑定给正确输出1,然后将正确输出发送给/dev/null设备(常用)

ls test.sh test1.sh &>/dev/null

# & 代表标准输出 ,错误输出,将所有标准输出与错误输出发送到/dev/null文件

注意:

1、shell遇到">"操作符,会判断右边文件是否存在,如果存在就先删除,并且创建新文件,不存在直接创建,无论左边命令执行是否成功,右边文件都会变为空;

2、">>"操作符判断右边文件,如果不存在,先创建;以添加方式打开文件,会分配一个文件描述符(不特别指定,默认为1,2),然后与左边的标准输出1或错误输出2绑定;

3、当命令执行完,绑定文件的描述符也自动失效,0,1,2空闲;

4、一条命令启动,命令的输入,正确输出,错误输出,默认分别绑定0,1,2文件描述符;

5、一条命令在执行前,先会检查输出是否正确,如果输出设备错误,将不会进行命令执行。

输入重定向:

实例:

例1:

# cat 从test.sh 获得输入数据,然后输出给文件file

cat > file < test.sh

例2:

cat > file << eof

test file.

this is test file.

eof

# << 代表的是"结束输入字符"的意思;当空行输入eof字符,输入自动结束,不用ctrl+D。

exec绑定重定向:

实例:

例1:

exec 6>&1

# 将标准输出与fd 6绑定

ls /proc/self/fd/

0  1  2  3  6

# 出现文件描述符6

exec 1>suc.txt

# 将接下来所有命令标准输出,输出到suc.txt文件

ls -al

# 执行命令,发现什么都不返回了,因为标准输出已经输出到suc.txt文件了

exec 1>&6

# 恢复标准输出

exec 6>&-

# 关闭fd 6描述符

ls /proc/self/fd/

0  1  2  3

说明:使用前先将标准输入保存到文件描述符6(文件描述符默认会打开0、1、2 还可以使用自定义描述符),然后对标准输出绑定到文件,接下来所有输出都会发生到文件,使用完后,恢复标准输出,关闭打开文件描述符6。

例2:

exec 3<>test.sh;

# 打开test.sh可读写操作,与文件描述符3绑定

while read line<&3

do

echo $line;

done

# 循环读取文件描述符3(读取的是test.sh内容)

exec 3>&-

exec 3<&-

# 关闭文件的输入输出绑定

扩展:>/dev/null 2>&1 与 2>&1 >/dev/null的区别

1、command >/dev/null 2>&1

# 相当于stdout="/dev/null"  stderr="$stdout"

# stderr也等于"/dev/null"

# 结果是标准输出和标准错误都指向了/dev/null,也就是所有的输出都被丢弃了;

2、command 2>&1 >/dev/null

# 相当于stderr="$stdout"      // stderr指向了屏幕,因为stdout还是指向屏幕

# stdout="/dev/null"            // stdout指向了/dev/null,但不会影响stderr的指向

# 结果是标准错误仍然被打印到屏幕上,而标准输出被丢弃;

三、管道与重定向的区别

1、左边的命令应该有标准输出 | 右边的命令应该能接受标准输入;

左边的命令应该有标准输出 > 右边只能是文件;

左边的命令应该需要标准输入 < 右边只能是文件;

2、管道触发两个子进程执行 "|" 两边的程序,而重定向是在一个进程内执行。

实例:

输入重定向:

例1:

cat test.sh | grep -n ‘echo‘

3:   echo "nice";

5:   echo "good";

7:   echo "pass";

9:   echo "shit";

# "|" 管道两边都必须是shell命令

例2:

grep -n ‘echo‘ < test.sh

3:   echo "nice";

5:   echo "good";

7:   echo "pass";

9:   echo "shit";

# "重定向"符号,右边只能是文件(普通文件,文件描述符,文件设备)

例3:

(sed -n ‘1,$p‘ | grep -n ‘echo‘) < test.sh

3:   echo "nice";

5:   echo "good";

7:   echo "pass";

9:   echo "shit";

# 等同于sed -n ‘1,$p‘ < test.sh | grep -n ‘echo‘

# 由于前面是管道,后面需要把test.sh内容重定向到sed,然后sed输出通过管道,输入给grep;需要将前面用"()"运算符括起来;在单括号内的命令,可以把它们看作一个命令;如果不加括号test.sh就是grep输入;

# 重定向运算符,在shell命令解析前,首先检查的(一个命令,执行前一定检查好它的输入、输出,也就是0、1、2 设备是否准备好),所以优先级会最高。

输出重定向:

例1:

cat test.sh > test.txt

cat test.sh | tee test.txt &>/dev/null

# 通过管道实现将结果存入文件,还需要使用命令tee,它把管道过来的标准输入写入test.txt,然后将标准输入复制到标准输出(stdout),重定向到/dev/null,所以不显示输出;

# ">" 输出重定向,往往在命令最右边(也可以用到命令中间),接收左边命令的输出结果,重定向到指定文件。

注:tee命令:输出屏幕同时输出到文件

例2:

ls test.sh test1.sh test2.sh 2>err.txt | grep ‘test‘

test.sh

test1.sh

# 目录下面有:test、test1文件,test2.sh不存在,因此将ls命令错误输出输入到err.txt,正确输出会通过管道发送到grep命令;

ls test.sh test1.sh test2.sh &>err.txt | grep ‘test‘

# 输出结果为空,&代表正确与错误输出都输入给err.txt,通过管道传递的数据为空,所以无显示;

# 同样 ">" 输出重定向符,优先级也是先解析,当一个命令有这个字符,它就会与左边命令标准输出绑定,准备好后,等待命令执行输出结果,然后接收。

时间: 2024-08-06 20:05:52

Linux shell管道与重定向及实例分析的相关文章

linux shell 管道命令(pipe)使用及与shell重定向区别

linux shell 管道命令(pipe)使用及与shell重定向区别 看了前面一节:linux shell数据重定向(输入重定向与输出重定向)详细分析 估计还有一些朋友是头晕晕的,好复杂的重定向了.这次我们看下管道命令了.shell管道,可以说用法就简单多了. 管道命令操作符是:"|",它仅能处理经由前面一个指令传出的正确输出信息,也就是 standard output 的信息,对于 stdandard error 信息没有直接处理能力.然后,传递给下一个命令,作为标准的输入 st

shell管道与重定向

输出重定向 ? 1 $ ls -l > lsoutput 这条命令将ls命令执行后的结果输入出到lsoutput文件中. 在linux shell中使用符号 > ,< 来完成输入输出的重定向,同时对应的有三种标准的文件描述符,0(标准输入),1(标准输出),2(标准错误),可以 单独的重写向其中的任何一种.你还可以重定向其他的文件描述符,但对标准文件描述符以外进行重定向的情况很少见. 默认情况下>符号在 文件已经存在时它会覆盖,需要使用set -o noclobber(或set -

shell管道和重定向

看了前面一节:linux shell数据重定向(输入重定向与输出重定向)详细分析 估计还有一些朋友是头晕晕的,好复杂的重定向了.这次我们看下管道命令了.shell管道,可以说用法就简单多了. 管道命令操作符是:”|”,它仅能处理经由前面一个指令传出的正确输出信息,也就是 standard output 的信息,对于 stdandard error 信息没有直接处理能力.然后,传递给下一个命令,作为标准的输入 standard input. 一.管道命令使用说明: command1正确输出,作为c

linux下管道及重定向

系统默认设定: 标准输入:STDOUT,0 标准输出: STDIN,1 标准错误输出: STDERR,2 2.I/O重定向: >:覆盖输出 set -C :禁止对已经存在的文件覆盖重定向 如需强制覆盖输出重定向:可使用 >| set +C :启用对已经存在的文件覆盖重定向 >>:追加输出 2> :  标准错误输出 2>> :标准错误追加方式 &> : 标准或错误输出至同一文件 举例说明:ls /etc/ &> /tmp/err.txt

Linux Shell:文件目录操作与实例

本文介绍基础的文件操作:创建,移动,编辑,删除 文件和文件夹 命令与案例: mkdir 创建目录 --创建两个目录 [email protected]:~$ mkdir test2 test3 --在test1下面创建一个新的目录mydir [email protected]:~$ mkdir test1/mydir --尝试在test100下面创建一个新的目录mydir,但不成功,因为test100这个目录不存在 [email protected]:~$ mkdir test100/mydir

Linux进程间通信—管道

Linux下的进程通信手段基本上是从UNIX平台上的进程通信手段继承而来的.而对UNIX发展做出重大贡献的两大主力AT&T的贝尔实验室及BSD(加州大学伯克利分校的伯克利软件发布中心)在进程间的通信方面的侧重点有所不同.前者是对UNIX早期的进程间通信手段进行了系统的改进和扩充,形成了"system V IPC",其通信进程主要局限在单个计算机内:后者则跳过了该限制,形成了基于套接口(socket)的进程间通信机制.而Linux则把两者的优势都继承了下来 linux进程间通信(

Linux Shell常用技巧(十一) 交互式使用shell

Linux Shell常用技巧(十一) 交互式使用shell 二十二. 交互式使用Bash Shell:     1.  用set命令设置bash的选项:    下面为set主要选项的列表及其表述: 选项名 开关缩写 描述 allexport -a 打开此开关,所有变量都自动输出给子Shell. noclobber -C 防止重定向时文件被覆盖. noglob -d 在路径和文件名中,关闭通配符. #打开该选项    /> set -o allexport   #等同于set -a    #关闭

Linux Shell常用技巧(十一)

二十二. 交互式使用Bash Shell:     1.  用set命令设置bash的选项:    下面为set主要选项的列表及其表述: 选项名 开关缩写 描述 allexport -a 打开此开关,所有变量都自动输出给子Shell. noclobber -C 防止重定向时文件被覆盖. noglob -d 在路径和文件名中,关闭通配符. #打开该选项    /> set -o allexport   #等同于set -a    #关闭该选项    /> set +o allexport  #等

Linux shell基础(十一)

二十二. 交互式使用Bash Shell:     1.  用set命令设置bash的选项:    下面为set主要选项的列表及其表述: 选项名 开关缩写 描述 allexport -a 打开此开关,所有变量都自动输出给子Shell. noclobber -C 防止重定向时文件被覆盖. noglob -d 在路径和文件名中,关闭通配符. #打开该选项    /> set -o allexport   #等同于set -a    #关闭该选项    /> set +o allexport  #等