웹상에서 system("~~") 함수 사용시
글쓴이: gnoygnas / 작성시간: 월, 2004/07/12 - 2:38오후
웹상에서 system("/usr/local/bin/test") 명령을 사용하여 특정한 프로그램을 실행시키려 합니다.
test 프로그램 안에는 단순히 printf("Test Ok!"); 만 있습니다.
/var/www/cgi-bin/app.cgi 내에 system("~~"); 함수가 포함 되어 있고,
물론 cgi를 위한 태그가 있습니다.
app.cgi 프로그램 내부 #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> int main(int argc, char *argv[]) { int result; // 웹을 이용한 프로그래밍일 경우 아래와 같이 꼭 써준다. printf("content-type: text/html\n\n"); printf("\nMain Test!\n"); ------> 출력됨 result=system("/usr/local/mpa/test"); ------> 결과값 출력 안됨 printf("Result : %d\n", result); ------> 출력됨 return 0; }
로컬상에서
# ./app.cgi
를 실행하면
Test Ok를 뿌려줍니다.
하지만 웹상에서하면 아무런 글자도 보여주질 않네요...
뭐가 문제인지 찾다찾다 못찾아서 이렇게 도움을 요청합니다. ^^;;;
Forums:
음...
이렇게 해주셨나요? 콘텐츠 타입을 꼭 찍어야 합니다.
H/W가 컴퓨터의 심장이라면 S/W는 컴퓨터의 영혼이다!
답변이 이렇게 빠를수가..
이 말씀 해 주실까봐 소스를 모두 올렸는데...^^;;
물론 말씀하신것처럼 컨텐츠 타입을 써줬습니다..
암튼 관심가져 주셔서 감사합니다..
One must, In fact, Love your pursuit
My home is below...Well, just go own your gait!
printf("Result : %d\n", result); 이 부
printf("Result : %d\n", result);
이 부분은 출력 되나요?.
------식은이 처------
길이 끝나는 저기엔 아무 것도 없어요. 희망이고 나발이고 아무 것도 없어.
popen()으로 받아서 출력하셔야 할것 같은데요.
popen()으로 받아서 출력하셔야 할것 같은데요.
------식은이 처------
길이 끝나는 저기엔 아무 것도 없어요. 희망이고 나발이고 아무 것도 없어.
Re:
예~ 그줄은 아무 이상없이 출력됩니다.
특정한 숫자가 찍히고요...(0,1 값이 아닌 68200 값)
휴~ 별거 아닌거 같은데 잡기가 이렇게 힘드네요..
app.cgi가 실행된다는 건 cgi-bin 디렉토리의 퍼미션 문제는 아니라는 말일테고....~~
One must, In fact, Love your pursuit
My home is below...Well, just go own your gait!
Re: 웹상에서 system("~~") 함수 사용시
음.. 이거 content-type 이 아니라 Content-type 으로 하면 안될까여?
앗!
앗! 죄송합니다. 눈팅하면서 지나가다가 답글을 달다보니... ㅜㅜ;
시스템 명령을 쓰면 쉘이 기동되고 해당 명령이 실행됩니다.
고로 웹데몬과 연결된 CGI의 파일 디스크립터와는 상관없이
터미널에 출력하려 하겠죠. 고로 출력 안되는 것이 당연합니다.
말씀하신것 처럼 popen으로 하셔야 합니다.
H/W가 컴퓨터의 심장이라면 S/W는 컴퓨터의 영혼이다!
쉘이 기동되어도 CGI의 파일 디스크립터에 지정된 stdin/stdout
쉘이 기동되어도 CGI의 파일 디스크립터에 지정된 stdin/stdout으로 출력됩니다. 무조건 터미널로 나가다뇨? 유닉스의 철학이 아닙니다. :(
제가 생각하는 문제의 가능성은 두가지입니다. 확인해보세요.
1. /.../mpa/test 프로그램이 stdout으로 출력이 나갑니까? stderr로 나가는 경우에는 문제가 될 수 있습니다. /.../mpa/test > file_out 식으로 테스트해보세요.
2. apache가 어떤 UID로 돌아가나요? nobody나 www 등의 UID로 돌겠죠? 이 UID의 SHELL이 어떻게 되나요?
테스트 결과
답변 감사합니다..
셀 상에서 아래의 명령어를 수행해보았습니다.
# /../mpa/test > file_out
내용은 아래와 같습니다.
보아하니 출력 순서가 system()에 의해 호출된 것이 먼저 보이네요...
참고로 제가 할것은 system("~~"); 으로 특정 프로그램을 실행해서
시리얼 포트 제어를 하는 것입니다.
예전에 했을때는 아무 이상이 없었는데, 왜 웹에서 안되는지 모르겠네요..
리눅스 버전이나, 컴파일 버전에 따라서 영향이 있을까요?
One must, In fact, Love your pursuit
My home is below...Well, just go own your gait!
system(PHP 3, PHP 4 , PHP 5)system
system
(PHP 3, PHP 4 , PHP 5)
system -- Execute an external program and display the output
Description
string system ( string command [, int return_var])
system() is just like the C version of the function in that it executes the given command and outputs the result. If a variable is provided as the second argument, then the return status code of the executed command will be written to this variable.
주의
사용자가 입력한 데이터를 이 함수로 넘길 때는, escapeshellarg()나 escapeshellcmd()를 사용하여, 사용자가 어떠한 명령을 실행하여 시스템을 조작하지 못하게 하여야 합니다.
참고: 이 함수를 사용하여 프로그램을 실행하고, 백그라운드에서 작업하게 내버려두려면, 그 프로그램의 출력이 파일이나 다른 출력 스트림을 향하게 하여야 합니다. 그렇지 않으면 PHP는 그 프로그램이 종료할 때까지 정지합니다.
The system() call also tries to automatically flush the web server's output buffer after each line of output if PHP is running as a server module.
Returns the last line of the command output on success, and FALSE on failure.
If you need to execute a command and have all the data from the command passed directly back without any interference, use the passthru() function.
https://nicesj.com
https://blog.nicesj.com
음...
앗 죄송합니다. 제가 이해를 잘 못 했습니다. 오늘 왜이러는지... ㅡ,.ㅡ;
기본적으로 "content-type"을 찍고 기타등등의 출력문을 하고 fflush(stdout);을
하지 않고 system();을 수행하면 fork->exec 순으로 되기 때문에 쉘이 수행되고
종료될 때, fflush();가 되면서 content-type 출력부분을 덮어 써버리게 되는군요.
그래서 웹데몬은 헤더로 인식해서 데이터를 다 버리게 되는 것이구요.
system(); 을 호출하기 전에 fflush();을 한 번 실행시켜 주시면 출력이
될껍니다.
PS : 위에 제가 쓴 글 popen(); 은 제가 착각해서 썼습니다. 오늘 정신이 없네요. *^^*
H/W가 컴퓨터의 심장이라면 S/W는 컴퓨터의 영혼이다!
system() 호출하시기 전에 fflush(stdout); 한번 때리세
system() 호출하시기 전에 fflush(stdout); 한번 때리세요.
Content-Type: text/html
은 대소문자 구별도 안하고 콜론(:) 다음에 빈칸이 없어도 잘 보이네요. ㅡ.ㅡ;;
RFC 2616에서는 HTTP header field 들은 RFC 822의 3.1 절에서 정의한 일반 포멧을 따른다고 되어있고,
RFC 822 의 3.4.7절 CASE INDEPENDENCE 에서는 대소문자 구별이 없다고 규정하고 있군요.
저것 때문에 문제를 일으킨 적이 있었던 기억이 있는데.. 구현이 잘못되었었나 봅니다.
소스 일부
많은 분들이 관심을 가져주셔서 하나하나 수정해나가고 있습니다...
다시한번 감사드리고요~
test.c의 소스 파일이고 웹상에서 http://ip/cgi-bin/test.cgi를 실행 시키면
아래와 같이 브라우져상에서 잘 뜹니다.
문제는 위 13번째 줄에서 나타난 것과 같이 시리얼 제어 프로그램을 작동시켜서
전등의 불을 on 시키는 것인데, 유독 웹상에서만 안됩니다.
Shell에서는 문제없이 전등이 On/Off 됩니다.
퍼미션 체크, 시리얼포트 체크....할것은 다 해봤는데, 문제를 찾지 못하고 있네요...~~
휴~....
One must, In fact, Love your pursuit
My home is below...Well, just go own your gait!
앗~
드뎌 해결했습니다..
역시나 문제는 아무것도 아닌것에서 비롯되네요...
밥 먹으면서 문득 스쳐가는 무언가 하나~, 혹시 시리얼포트 퍼미션?
올라오자마자 확인해보니 역시나 시리얼 포트 (ttyS0)의 퍼미션 문제였습니다.
전에 레드햇에서 작업 했을때는 기본적으로 crw-rw-rw로 되었는지
시리얼포트 퍼미션에 신경을 안썼는데, 와우 7.1에서는 디폴트로
crw-rw----이었습니다....
아무쪼록 관심가져 주신 분들께 감사드립니다.
좋은 하루 되세요~~ ^^;;;;
One must, In fact, Love your pursuit
My home is below...Well, just go own your gait!
댓글 달기