[완료]popen시 명령어 수행
글쓴이: yangsee / 작성시간: 금, 2009/11/13 - 8:32오전
간단한 프로그램 작성시 오류가 있어서 질문드립니다.
system call을 호출할 때 popen을 사용합니다.
for문에서 tar 파일 16개를 popen으로 풀도록 했습니다.(1개가 25M, 1개 tar = 888개 파일 포함)
16개의 tar가 다 풀리고 나서, 888 * 16 개의 파일의 압축해제(gzip -d *.gz)도 수행하게 하였습니다.
문제는 tar가 제대로 안 풀린다는 것입니다.
각 tar파일의 초반에 있는 파일만 풀리고 나머지는 파일이 미생성됩니다.
프로그램상의 오류메시지도 없습니다.
자원문제인가?
직접 쉘에서 수행할 때는 문제가 없었습니다.
도움 부탁드립니다.
Forums:
음...
코드를 어떻게 작성하셨는지 모르니, 의견 드리기가 애매합니다만..
popen() 이후에 곧바로 pclose() 가 호출된다면..
stream 이 닫히고 프로세스는 진행상태와 무관하게 바로 종료됩니다.
(보충 : fork 된 녀석이 pipe 에 데이터를 쓰는 경우에만, EPIPE 를 찍고 종료됨)
tar 가 풀릴 만큼의 충분한 시간적 여유를 두고 sleep 하거나.. (근데 이건 예측 불가..)
fp 가 NULL 을 return 할 때까지 fgets 를 호출해 주어야..
tar 가 성공한 것으로 간주 할 수 있습니다.
tar 가 찍어내는 메시지가 필요한 경우라 아니라면...
그냥 system() 함수를 쓰는 편이 나을 것 같습니다.
추가)
(이런 경우에 굳이 popen 을 써야 할 이유는 없겠지만...)
popen() 을 쓸 때, 명령의 stdout 을 > /dev/null 로 날려버리면..
popen() 직후에 pclose() 를 호출하더라도, 명령이 완전히 수행된 후에 종료되는군요.
되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』
되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』
예제
코드는 다음과 같습니다.
popen시 &를 안주면 Broken Pipe 오류가 납니다.
&를 주면 pclose전에 sleep을 주어도 완전히 파일을 풀지 못합니다.
(50%정도만 풀리고 다음파일로 넘어갑니다.)
쉘에서 직접 명령을 주면 5초면 풀리는데, sleep은 2분을 주어도 tar가 끝나지 않네요. --;
for(hour=0; hour<25; hour++)
{
sprintf(strTemp, "tar xvf %s/%08d%02d.tar &", dir, day, hour);
printf("%s\n", strTemp); //test
if((pfp = popen(strTemp, "r")) == NULL)
printf("** %s:%d ** popen == NULL",__FILE__,__LINE__);
else
pclose(pfp);
}
음...
popen 에서 EPIPE 가 떨어진다는 뜻인가요..?
popen() 후에, fork 된 프로세스가 tar 의 결과를 pipe 에 쓰려는데..
pclose() 가 바로 호출되면서, pipe 가 사라지니까 EPIPE 를 리턴할 텐데요.. ;;
(popen 은 정상적으로 수행될 것 같다는 뜻)
흠.. popen 에서 호출하는 shell 과 관련이 있는 건지는 확실히 모르겠군요.
아래는 fedora, bash 에서 테스트한 코드입니다.
첫번째는.. stdout 을 /dev/null 로 날려버리면 pipe 에 쓸 데이터가 없으니..
EPIPE 가 안 떨어지므로 프로세스가 계속해서 수행될 것이고..
두번째는 프로세스가 정상적으로 종료할 때까지.. pipe 의 내용을 읽어들이는 코드입니다.
되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』
되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』
말씀하신 2가지 케이스 모두 잘 됩니다.
저는 sunOS에서 테스트를 했습니다.
말씀해주신 2가지 경우 모두 잘 됩니다.
제가 적은 방법으로는 popen이 제대로 수행이 안되더라는. --;
감사합니다.
감사합니다.
> /dev/null 을 달아주니 금새 정상동작 합니다.
감사드립니다.
system은 호출시마다 인자가 틀려져서 popen을 사용하였습니다.
댓글 달기