加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

shell – POSIX’tee’命令如何工作?

发布时间:2020-12-15 21:34:43 所属栏目:安全 来源:网络整理
导读:tee newOutputFile existingInputFile newOutputFile2 T恤究竟会如何参与争论?会这样吗? Tee将首先处理newOutputFile existingInputFile 因此,existingInputFile的内容将写入newOutputFile newOutputFile newOutputFile2 因此newOutputFile的内容将写入new
tee newOutputFile< existingInputFile> newOutputFile2

T恤究竟会如何参与争论?会这样吗?

> Tee将首先处理newOutputFile< existingInputFile
因此,existingInputFile的内容将写入newOutputFile
> newOutputFile> newOutputFile2
因此newOutputFile的内容将写入newOutputFile 2

我正在尝试编写一个处理此特定命令的shell.但是,我很困惑哪个顺序传递给tee的参数.我编写程序的方式就可以了

tee newOutputFile2< existingInputFIle

解决方法

tee命令是一个常规的Unix程序,就像sh或sort或cat一样.

所有涉及处理的I / O重定向工作< existingInputFile和> newOutputFile2由shell在调用tee命令之前完成(在创建将执行tee命令的进程的fork之后).调用该命令时,其标准输入来自existingInputFile,其标准输出将转至newOutputFile2.给tee的唯一参数是argv [0](字符串tee)和argv [1](字符串newOutputFile),以及用于标记参数列表末尾的空指针.

特别注意shell不参与existingInputFile的实际读取;它只是打开它进行读取并将其连接到tee的标准输入,但不知道tee命令是否实际读取它.同样,shell不参与实际写入newOutputFile2;它只是打开并截断它(或创建它)并将它连接到tee的标准输出,但不知道tee命令是否实际上向它写了任何东西.在此上下文中,当tee命令运行时,父shell完全被动,不执行I / O.

按照设计,tee读取其标准输入,并将所有内容的一个副本写入其参数列表中给出的每个文件,并将另一个副本写入标准输出.

I was under the impression that the shell was involved in the actual reading and writing of the files. So when I call execvp,it only takes in the command (in this case tee) and the final file to write the contents to (in this case newOutputFile2). I am trying to create my own shell program,how would I do the I/O redirection. Is this where dup2 comes into play?

shell只涉及打开和关闭,但不涉及文件的读写.在命令行中,tee newOutputFile< existingInputFile> newOutputFile2,命令是tee,唯一的另一个参数是newOutputFile.通常,命令(在本例中为tee)不知道为其提供标准输入的文件的名称,也不知道它在其标准输出上写入的文件的名称.实际上,特别是对于tee,输入通常是管道而不是文件,输出通常也是管道而不是文件:

some_command arg1 arg2 | tee some_command.log | another_command its_arg1 its_arg2 > output.file

在您自己的shell程序中,您可以使用dup2()复制您单独打开的文件描述符,以便它成为标准输入:

// Redirect standard input from existingInputFile using dup2()
char *i_filename = "existingInputFile";
int fd = open(i_filename,O_RDONLY);
if (fd < 0)
{
    fprintf(stderr,"unable to open file %s for reading (%d: %s)n",i_filename,errno,strerror(errno));
    exit(1);
}
dup2(fd,STDIN_FILENO);
close(fd);  // Crucial!

请注意,在此方案中关闭fd很重要.否则,运行该命令时至少打开一个未在命令行中指定的额外文件描述符.你有一个类似的标准输出重定向代码块.

或者您可以使用:

// Redirect standard input from existingInputFile
close(0);
char *i_filename = "existingInputFile";
int fd = open(i_filename,strerror(errno));
    exit(1);
}
assert(fd == 0);

// Redirect standard output to NewOutputFile2
close(1);
char * o_filename = "newOutputFile2";
fd = open(o_filename,O_WRONLY|O_CREAT|O_TRUNC,0644); // Classically 0666
if (fd < 0)
{
    fprintf(stderr,"unable to open file %s for writing (%d: %s)n",o_filename,strerror(errno));
    exit(1);
}
assert(fd == 1);

这是因为open()返回最低可用的先前未打开的文件描述符,因此通过关闭0,您知道open()将在成功时返回0并在失败时返回-1(即使先前已关闭0).然后,通过归纳,您知道在关闭1之后,open()将在成功时返回1,在失败时返回-1(即使先前已关闭1).除非命令行包括I / O重定向,例如2> / dev / null或2>& 1或类似的东西,否则通常不会修改标准错误.

如果您愿意,可以将0644写为:

O_IRUSR|O_IWUSR|O_IRGRP|O_IROTH

(并且如果你想使用组和其他写权限(0666),则添加| O_IWGRP | O_IWOTH;无论如何都将通过umask修改权限).就个人而言,我发现八进制文件更容易阅读,但是在O_Ixyyy名称发明之前,我开始使用八进制权限.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读