我编写了这段代码来覆盖Ubuntu中的cat
命令。 cat
指令的以下三种格式正常工作,但其余格式无效。
工作人员:
不工作:
我将终端参数发送到上面列出的程序。另一个问题是每个文件也包含Enter your String:
,它也不应该。这里是代码:
int main(int argc, char *argv[])
{
int readbytes,fp;
char buf[1024];
if(argc==1)
{
printf("Enter your String :\n\n");
readbytes=read(STDIN_FILENO,buf,1024);
write(STDOUT_FILENO,buf,readbytes);
}
else if(argc==2)
{
fp=open(argv[1],O_RDONLY);
dup2(0,fp);
close(fp);
readbytes=read(STDIN_FILENO,buf,1024);
write(STDOUT_FILENO,buf,readbytes);
}
else if(argc==3)
{
if(argv[1][0]=='<')
{
fp=open(argv[2],O_WRONLY|O_CREAT,S_IRWXU);
dup2(1,fp);
close(fp);
readbytes=read(STDIN_FILENO,buf,1024);
write(STDOUT_FILENO,buf,readbytes);
}
else if(argv[1][0]=='>')
{
fp=open(argv[2],O_RDONLY);
dup2(1,fp);
close(fp);
readbytes=read(STDIN_FILENO,buf,1024);
write(STDOUT_FILENO,buf,readbytes);
}
}
else if(argc==4)
{
printf("inside");
fp=open(argv[1],O_RDONLY);
dup2(0,fp);
close(fp);
fp=open(argv[3],O_WRONLY|O_CREAT,S_IRWXU);
dup2(1,fp);
close(fp);
readbytes=read(STDIN_FILENO,buf,1024);
printf("%c",buf);
write(STDOUT_FILENO,buf,readbytes);
}
return 0;
}
更新
我在代码中做了William建议的更改,其余的代码工作正常,但./catf File.txt ">" File2.txt
仍然无效。那是为什么?
if(argc==4)
{
printf("inside4");
fp=open(argv[1],O_RDONLY);
dup2(fp,0);
close(fp);
fp=open(argv[3],O_WRONLY|O_CREAT|O_TRUNC,S_IRWXU);
dup2(fp,1);
close(fp);
readbytes=read(STDIN_FILENO,buf,1024);
//printf("%c",buf);
write(STDOUT_FILENO,buf,readbytes);
}
上述问题的原因是什么?
答案 0 :(得分:1)
当您调用cat > file1.txt
时,*argv[1]
不 <
。相反,argc
为1,并且在调用main
时,stdout已与文件关联。如果你想通过shell传递<
作为参数,你需要引用它:
$ cat '<' filename
此外,您对dup2
的调用反转了相反的论点; STDOUT_FILENO
应该是第二个参数,而不是第一个参数。您在argc==2
子句中的方式是关闭fp
并将其重新打开到原始标准输出。
答案 1 :(得分:0)
正如@William Pursell所说,重定向由shell处理,而不是由程序处理。因此程序永远不会在argv[]
中看到重定向符号。
但是,您可以通过测试isatty(fd)
来判断是否已重定向。遗憾的是,您无法以任何标准方式确定要将哪个文件重定向到哪个文件,例如,您可能会被重定向到管道或从管道重定向。
Linux上存在可能的黑客攻击,您可以阅读/proc/$$/fd
(其中$$
是您当前的PID)并查看fds 0,1,2的符号链接。但是,并非所有UNIX都支持此功能。