popen + pclose 셸 명령 실행

2853 단어 LinuxProgramming
에서 시스템 이 셸 명령 을 실행 하 는 방법 을 소 개 했 습 니 다. 시스템 반환 값 이 혼 란 스 러 워 이해 하기 어렵 고 popen 은 하위 프로 세 스 표준 출력 을 처리 하 는 데 편리 합 니 다.
메모: 파 이 프 는 표준 출력 만 처리 할 수 있 고 표준 오류 출력 은 처리 할 수 없습니다.
popen 과 pclose 의 실현 은 system 과 유사 하여 파 이 프 를 만 드 는 작업 이 한 단계 더 많아 졌 습 니 다.
popen 은 FILE 핸들 을 성공 적 으로 되 돌려 주 었 습 니 다. NULL 을 되 돌려 주지 못 했 습 니 다. 실패 한 원인 은 fork 나 pipe 가 실 패 했 을 수도 있 고 메모리 할당 에 실 패 했 을 수도 있 습 니 다.
pclose 실패 반환 - 1, 성공 하면 exit status 로 돌아 갑 니 다. system 과 유사 합 니 다. 사용 해 야 합 니 다. WIFEXITED, WEXITSTATUS 등 명령 반환 값 을 가 져 옵 니 다.
또한, 시스템 과 유사 합 니 다. pclose 는 프로 세 스 가 종 료 될 때 까지 기다 릴 것 입 니 다. 프로 세 스 가 종 료 될 때 까지 기다 리 지 않 으 면 error 는 다음 과 같이 설정 합 니 다. ECHILD.
주의:
1. pclose 는 하위 프로 세 스 를 회수 하기 위해 좀 비 프로 세 스 가 발생 하지 않도록 합 니 다.
2. 시스템 과 마찬가지 로 SIGCHLD 여전히 popen 에 영향 을 줄 수 있 습 니 다. 예제 프로그램 을 보십시오.
#include 
#include 
#include 
#include 
#include 

typedef void (*sighandler_t)(int);

int main(int argc, char* argv[])
{
    char cmd[1024];
    char line[1024];
    FILE* pipe;
    int rv;

    if (argc != 2)
    {
        printf("Usage: %s 
", argv[0]); return -1; } // pclose fail: No child processes signal(SIGCHLD, SIG_IGN); snprintf(cmd, sizeof(cmd), "ls -l %s 2>/dev/null", argv[1]); //sighandler_t old_sighandler = signal(SIGCHLD, SIG_DFL); pipe = popen(cmd, "r"); if(NULL == pipe) { printf("popen() failed: %s
", cmd); return -1; } while(fgets(line, sizeof(line),pipe) != NULL) { printf("%s", line); } rv = pclose(pipe); //signal(SIGCHLD, old_sighandler); if (-1 == rv) { printf("pclose() failed: %s
", strerror(errno)); return -1; } if (WIFEXITED(rv)) { printf("subprocess exited, exit code: %d
", WEXITSTATUS(rv)); if (0 == WEXITSTATUS(rv)) { // if command returning 0 means succeed printf("command succeed
"); } else { if(127 == WEXITSTATUS(rv)) { printf("command not found
"); return WEXITSTATUS(rv); } else { printf("command failed: %s
", strerror(WEXITSTATUS(rv))); return WEXITSTATUS(rv); } } } else { printf("subprocess exit failed
"); return -1; } return 0; }

설명:
1. SIGCHLD 를 무시 한 후 pclose 는 하위 프로 세 스 종료 정 보 를 회수 할 수 없습니다. errno 는 ECHILD, 잘못된 정 보 는 "No child processes"입 니 다.
2. 파이프 가 stderr 를 캡 처 할 수 없 기 때문에 stderr 를/dev/null 로 재 설정 하 라 고 명령 합 니 다.

좋은 웹페이지 즐겨찾기