2012-12-10 2 views
-1

우분투에서 cat 명령을 무시하기 위해이 코드를 작성했습니다. cat 명령어에 대한 다음 세 가지 형식이 제대로 작동하지만 나머지는 작동하지 않습니다.C에서 표준 입력 및 출력 오버라이드

근무 것들> File.txt를

  • ./catf < File.txt를
  • 가 작동하지

    • ./catf :을 File1 ./catf

      • . 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이고 stdout은 이미 main이 호출 될 때까지 파일과 연관되어 있습니다. 당신이 쉘을 통해 인수로 <를 전달하려는 경우, 당신은 그것을 인용해야합니다 dup2 당신의 호출이 반전 인수가

    또한
    $ cat '<' filename 
    

    ; STDOUT_FILENO은 첫 번째가 아닌 두 번째 인수 여야합니다. argc==2 절에있는 방법은 fp을 닫고 원래 표준 출력으로 다시 여는 것입니다.

    +0

    업데이트 된 질문보기 – Alfred

    +0

    실행 파일의 이름을 변경해도 내 대답이 변경되지 않습니다. 유일한 차이점은 나의 예제는'./catf '<'filename'이어야한다는 것이다.프로그램을 실행하는 관점에서 보면'argv [0]'은'cat' 대신에'catf'이지만 argc는 여전히 1이고'argv [1]'은'<'대신에 여전히 NULL입니다. 당신은 질문에서와 같이 명령을 호출합니다. –

    +0

    확인. 왜 'Not Working'에 열거 된 것들이 작동하지 않는 걸까요? – Alfred

    0

    @William Pursell에 따르면 리디렉션은 프로그램이 아니라 셸에서 처리합니다. 따라서 프로그램에서는 argv[]의 리디렉션 기호를 볼 수 없습니다.

    그러나 isatty(fd)을 테스트하여 리디렉션되었는지 확인할 수 있습니다. 유감스럽게도 어떤 표준 방식 으로든 리디렉션되는 파일을 알 수 없습니다. 예를 들어 파이프로 /에서 리디렉션 될 수 있습니다.

    Linux에서 해킹이 가능한 경우 /proc/$$/fd (여기서 $$은 현재 PID 임)을 읽고 fds 0,1,2의 심볼릭 링크를 살펴볼 수 있습니다. 하지만 모든 유닉스에서 지원되는 것은 아닙니다.