覆盖 C 语言中的标准输入和输出



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

工作:

  • ./catf> 文件.txt
  • ./catf <文件.txt>

不工作:

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

我正在将终端参数发送到上面列出的程序。另一个问题是每个文件也包含不应该包含Enter your String:。这是代码:

int main(int argc, char *argv[])
{
    int readbytes,fp;
    char buf[1024];
    if(argc==1)
    {
        printf("Enter your String :nn");
        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);
    }

上述问题的原因是什么?

当你调用cat > file1.txt时,*argv[1]不是<。 相反,argc为 1,并且在调用 main 时 stdout 已经与文件关联。 如果你想通过 shell 将<作为参数传递,你需要引用它:

$ cat '<' filename

此外,您对dup2的调用颠倒了论点; STDOUT_FILENO应该是第二个参数,而不是第一个参数。 您在 argc==2 子句中的方法是关闭fp并将其重新打开到原始标准输出。

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

但是,您可以通过测试isatty(fd)来判断您是否被重定向。 不幸的是,您无法以任何标准方式判断您被重定向到哪个文件,例如,您可能会被重定向到管道/从管道重定向。

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

最新更新