跟我一起写Shell脚本之二十三--标准输入和输出,以及重定向

1、什么是标准输入和输出

当我们执行一个shell命令行时,一般会自动打开三个标准文件
1)标准输入文件(stdin),通常对应终端的键盘;
2)标准输出文件(stdout),默认对应终端的屏幕;
3)标准错误输出文件(stderr),默认对应终端的屏幕。

命令从标准输入文件中得到输入数据,将正常输出数据输出到标准输出文件,而将错误信息送到标准错误文件中。

因为Linux里一切皆是文件,所以标准输入和输出也不例外,也是文件。是文件就有文件描述符,这三个标准文件的文件描述符是固定的:

1)标准输入文件 0;
2)标准输出文件 1;
3)标准错误输出文件 2。

所以,总结一下标准输入、输出、错误输出:

文件描述符 描述 默认设备 文件句柄
0 标准输入(stdin) 键盘 /proc/self/fd/0
1 标准输出(stdout) 屏幕 /proc/self/fd/1
2 标准错误输出(stderr) 屏幕 /proc/self/fd/2

2、输入重定向

2.1 默认输入(从键盘获取输入)

当我们在终端输入cat命令,会发现它会等在那里,它在等什么呢?就在等我们的输入。

当我们输入aaa,它就会输出aaa:

$ cat
aaa
aaa

当我们输入其他字符后回车,他就会输出其它字符;当我们Ctrl C它才结束:

$ cat
aaa
aaa
abcdefg
abcdefg
^C
$

以上例子可以看出,它的标准输入是键盘,cat将键盘的输入作为输入,然后输出到默认的标准输出(屏幕)上。

2.2 从文件输入(将标准输入重定向到文件)

我们可以用以下几种方式,从某个文件获得输入而不是从键盘获得输入:

cat xxxfilename

cat < xxxfilename

cat 0< xxxfilename

$ cat xxxfilename.txt 
Hello!
It is only a test file!
This is the 3rd line.

$ cat < xxxfilename.txt 
Hello!
It is only a test file!
This is the 3rd line.

$ cat 0< xxxfilename.txt 
Hello!
It is only a test file!
This is the 3rd line.

其他命令也类似:

$ wc -l xxxfilename.txt 
3 xxxfilename.txt

$ wc -l < xxxfilename.txt 
3

$ wc -l 0< xxxfilename.txt 
3

2.3 从here文档输入(将标准输入重定向到here文档)

“here文档”的重定向操作符使用<<,它将一对分隔符(分隔符可以任意指定)之间的正文重定向输入给命令。看个例子可能更容易理解:

$ cat<<myflag
> aaaa
> bbb
> cccddd
> eee
> fff
> myflag
aaaa
bbb
cccddd
eee
fff

以上我们在我们设定的分隔符(myflag)之间,输入很多行的内容,作为cat的输入。结果它就将其内容输出来了。

同样我们用wc命令试一下:

$ wc -l <<myflaggg
it is my line1
line2
line3
line4
myflaggg

4

同样,我们可以用这个方法写入到文件:

$ cat > xxxfilename2.txt << myflag
> line1
> line2
> line3
> hehe end
> myflag


$ cat xxxfilename2.txt 
line1
line2
line3
hehe end

以上我们将myflag之间的内容,作为cat > xxxfilename2.txt命令的输入。而cat > xxxfilename2.txt命令又将其输入输出到了文件xxxfilename2.txt。

3、输出重定向

输出重定向是指把命令的标准输出或错误输出重新定向到指定文件中。这样,该命令的输出就不显示在屏幕上,而是写入到指定文件中。

输出重定向有如下用处:当我们希望把一个命令的输出,输出到某个文件,方便查看或者存储、转发时。

总结一下输出重定向的结果:

命令 作用 备注
命令 > filename

将“命令”执行的正确结果,覆盖的方式写到文件filename里。

错误结果显示在屏幕上。

等同于:

命令 1> filename

命令 >> filename

将“命令”执行结果,追加的方式写到文件filename里。

错误结果显示在屏幕上。

等同于:

命令 1>> filename

命令 &> filename 将“命令”执行的正确结果,和错误结果,都以覆盖的方式写到文件filename里。

等同于:

命令 > filename 2>&1

命令 &>> filename 将“命令”执行的正确结果,和错误结果,都以追加的方式写到文件filename里。

等同于:

命令 >> filename 2>>&1

命令 2> filename

将“命令”执行的错误结果,以覆盖的方式写到文件filename里。

正确结果显示在屏幕上。

命令 2>> filename

将“命令”执行的错误结果,以追加的方式写到文件filename里。

正确结果显示在屏幕上。

注意:如果filename为/dev/null,则是丢弃其内容的意思。

4、彩蛋

为了验证某个进程/proc/进程号/fd/0、1、2三个标准输入输出的文件描述符,我们可以做这么一个实验:

1)在终端输入cat,然后回车

$ cat

2)然后打开另一个终端,输入ps -aux,我们查找下刚才输入cat后运行的pid:

wjbvb2    3591  0.0  0.0  14512   768 pts/4    S+   08:01   0:00 cat

由以上可以看出,其pid为3591。

3)然后我们在第二个终端里输入:

echo aaabbbccc > /proc/3591/fd/0

回车后查看第一个终端的情况:

$ cat
aaabbbccc

由此可见,我们将进程3591的标准输入里输入aaabbbccc,它就会将标准输入的内容输出到屏幕上。

=========================================================================

注意:本文为本人原创,版权所属为个人所有,欢迎转载,但是转载请注明出处。

=========================================================================

Guess you like

Origin blog.csdn.net/sjwangjinbao/article/details/118851315