Shell 구현 (4) 명령 실행 (파이프 구현 포함)

7496 단어 Linux 딥 러 닝
기본 사고방식:
  • 우선 명령 집행 의 실현
  • exec 족 함 수 를 통 해 이 루어 진
  • 그 다음 에 파이프 의 실현 이다. 두 가지 실현 방안 이 있 는데 하 나 는 pipe 함 수 를 호출 하 는 것 이다. 그러나 자신 이 하 나 를 쓸 수 있 는 이상 왜 이런 어 리 석 은 함 수 를 기억 해 야 합 니까?
  • pipe 함 수 를 호출 하 는 것 은 머리 가 없 기 때문에 2 규모 의 파일 설명자 배열 이 필요 합 니 다. 파이프 에 쓰 인 흐름 과 파이프 에서 읽 은 흐름
  • 을 표시 합 니 다.
  • 자신 이 하 나 를 디자인 해도 머리 가 없고 파일 을 파이프 의 운반 체 로 만 든 다음 에 방법 은 위의 것 과 유사 하 다.


  • 구체 적 인 실현:
  • 첫 번 째 방안 은 코드 가 비교적 간단 한 자신 이 실현 한 pipe 버 전
  • 이다.
    void run_shell (  )
    {
        int i,j;
        fd[0] = open ( PIPE_FILE , O_CREAT|O_RDONLY , 0666 );//             
        fd[1] = open ( PIPE_FILE , O_CREAT|O_WRONLY|O_TRUNC , 0666 );//             
        for ( i = 0 ; i < cnt_group ; i++ )//        
        {
            l = group[i].first;
            r = group[i].last;
            int pid = fork();//           
        //fork       ,          0,       0
            if ( pid == 0 )
                run_command ( l , r-1 ); //    (           )
            else 
                waitpid ( 0 , NULL , 0 );//     ,         (            )
        }
    }

    그 다음 에 명령 을 집행 하고 파이프 의 설 계 를 생각 하 니 재 귀적 인 생각 이 들 었 다. 교체 도 잘 되 지만 게 으 른 지 재 귀적 으로 쓰 는 지...
    void run_command ( int l , int x )
    {
        //printf ( "%d %d
    " , l , x );
    pid_t pid; if ( x != l )// , { pid = fork(); if ( pid==0 )// run_command ( l , x-1 ); else waitpid ( 0 , NULL , 0 );// } //printf ( "where am i %d
    " , x );
    // if ( x != l ) dup2 ( fd[0] , fileno(stdin) ); if ( x != r-1 ) dup2 ( fd[1] , fileno(stdout) );     // execvp ( cmd[x].cmd , cmd[x].param ); }
  • 두 번 째 방안 은 라 이브 러 리 의 pipe 함 수 를 이용 하여 실현 하 는 방안
  • void run_shell ( )
    {
        int pipe_fd[2];
        int status;
        pipe(pipe_fd);
        pid_t child1,child2;
        if ((child1=fork())!=0)//   
        {
            if ( (child2 = fork()) == 0 )//   
            {
                close ( pipe_fd[1] );
                close ( fileno ( stdin ) );
                dup2 ( pipe_fd[0] , fileno(stdin));
                close ( pipe_fd[0] );
                execvp ( cmd[1].cmd , cmd[1].param );
            }
            else 
            {
                close ( pipe_fd[0]);
                close ( pipe_fd[1]);
                waitpid ( child2 , &status , 0 );
            }
            waitpid ( child1 , &status , 0 );
        }
        else
        {
            printf ( "subshell 3cmd %d
    "
    , getpid() ); close ( pipe_fd[0] ); close ( fileno(stdout)); dup2 ( pipe_fd[1] , fileno(stdout)); close ( pipe_fd[1] ); execvp ( cmd[0].cmd , cmd[0].param ); } }

  • 필요 한 함수
  • 1.
  • int execvp(const char *file ,char * const argv []);
    //execvp()  PATH                 file     ,         ,        argv         。
  • 2.
  • pid_t waitpid(pid_t pid,int * status,int options);
    //waitpid()            ,             。
  • 3.
  • #include
    int pipe(int fd[2])
    //      fd[2]:          ,                  
    //       0     -1
  • 4.
  • int dup2(int oldhandle,int newhandle);
    //      
  • 5.
  • #include
    int open(constchar*pathname,intflags);
    int open(constchar*pathname,intflags,mode_tmode);
    //   :          ,    -1
  • 6.
  • close( int )
    //    

    좋은 웹페이지 즐겨찾기