2012-12-10 155 views
-1

我编写了这个代码来覆盖Ubuntu中的cat命令。 cat指令的以下三种格式正常工作,但休息不起作用。C中的标准输入和输出标准输入和输出

工作的:

  • ./catf> FILE.TXT
  • ./catf < FILE.TXT

不工作:

  • ./catf文件1。 txt> File.txt
  • ./catf File.txt

我正在向上面列出的程序发送终端参数。另一个问题是每个文件还包含Enter your String:也是它shouldn't.Here是代码:

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; 
} 

UPDATE:

我做的代码由威廉建议的修改和的休息代码工作正常,但这./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); 
    } 

上述问题的原因是什么?

回答

1

当您调用cat > file1.txt时,*argv[1]而不是<。相反,argc为1,并且在调用main时已将stdout与该文件关联。如果你想通过<经由外壳的说法,你将需要引用它:

$ cat '<' filename 

而且,你的dup2调用有逆转的论据; STDOUT_FILENO应该是第二个参数,而不是第一个参数。你在argc==2条款中的方式是关闭fp并将其重新打开到原始标准输出。

+0

查看我更新的问题 – Alfred

+0

更改可执行文件的名称不会以任何重要的方式改变我的答案。唯一的区别是我的例子应该是'./catf'<'filename'。在运行程序方面,现在'* argv [0]'是'catf'而不是'cat',但是'argc'仍然是1,而'* argv [1]'仍然是NULL而不是'<你在你的问题中调用该命令。 –

+0

好的。为什么'Not Working'下列出的那些不起作用? – Alfred

0

正如@William Pursell所说,重定向由shell处理,而不是由程序处理。所以程序永远不会看到argv[]中的重定向符号。

但是,您可以告诉您是否已通过测试isatty(fd)重定向。不幸的是,你不能以任何标准的方式知道你被重定向到哪个文件,例如你可能被重定向到/来自管道。

Linux上有可能的黑客攻击,您可以阅读/proc/$$/fd(其中$$是您当前的PID)并查看fds 0,1,2的符号链接。尽管这在所有UNIX上都不受支持。

相关问题