超越C中的标准输入和输出

时间:2012-12-10 13:44:36

标签: c unix stdio cat

我编写了这段代码来覆盖Ubuntu中的cat命令。 cat指令的以下三种格式正常工作,但其余格式无效。

工作人员:

  • ./ catf> file.txt的
  • ./ catf< file.txt的

不工作:

  • ./ catf File1.txt> file.txt的
  • ./ catf File.txt

我将终端参数发送到上面列出的程序。另一个问题是每个文件也包含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);
    }

上述问题的原因是什么?

2 个答案:

答案 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都支持此功能。