天天看点

shell重定向小记

对于int型的,使用open,write,read,close操作,对于FILE*型的使用fopen,fwrite,fread,fclose操作

标准输入,int fd = 0,int fd = STDIN_FILENO,FILE *f = stdin,shell重定向标准输入使用"<",比如./hello <words.txt,那么hello可以从fd=0或者f=stdin里面读取words.txt文件中的内容,平时都是./hello words.txt这样,可以从argv[1]中读取文件名,然后再open/read/close。

有种特殊的情况是这样的,不一定需要使用EOF,任意单词都可以,首尾相同:

有些程序可以接收参数"-",表示从标准输入中读取文件内容

标准输出,int fd = 1,int fd = STDOUT_FILENO,FILE *f = stdout,shell重定向标准输出使用">"(覆盖方式),或者">>"(append方式),">"和">>"前面的默认数字是"1",比如:

错误输出,int fd = 2,int fd = STDERR_FILENO,FILE *f = stderr,shell重定向错误输出使用"2>"(覆盖方式),或者"2>>"(append方式),和标准输出类似,注意使用">"对错误输出无效:

并不一定是2这个数字,而是指错误输出,例如:

有时候常用到"2>&1"这种,是将错误输出重定向到标准输出,为什么要加"&"呢,因为不加就会重定向到一个名为"1"的文件

如果标准输出和错误输出都需要重定向,那么应该先写标准输出的,再写错误输出的:

/dev/null就是个垃圾桶,扔进去的都没了,类似还有/dev/zero,从里面可以读出来无数的0

shell 使用"|"将上一条命令的标准输出,作为下一条命令的标准输入,例如:

可以使用proc看到每个进程打开了多少fd,以及fd打开的是谁(self可以替换为具体的pid):

每一个终端都对应/dev/pts下面的一个文件,向对应的文件写入数据,那么将会显示在我们的终端上面,也可以和别的用户打招呼,如果你sudo的话:

还有个比较有意思的就是pipe文件,注意ls -l显示出的文件类型为"p":

可以一个进程将输出写到mypipe,另一个进程从mypipe文件读取第一个进程输出的内容,

甚至可以这样玩,先在一个终端上启动nc服务器:

另一个终端使用pipe文件,将bash的标准输出给nc的标准输入,nc的标准输出给bash的标准输入:

这样的话,就可以在第一个终端,输入shell命令了,控制了第二个终端所在的机器

关于time,你没法重定向time的输出:

因为time是shell builtin的命令,重定向是由shell自己来处理的,使用time命令的时候,重定向的东西被当做普通参数了。所以time得到的argv={"ls", ">/dev/null", "2>&1"},而不是{"ls"}

如果是普通的程序,比如/usr/bin/time,重定向的东西就是重定向,没法被当做普通参数,所以/usr/bin/time可以被重定向掉: