14Day Study
[[[[[프로세스간 통신: 파이프(pipe)]]]]]
< myserver 서버에 id로 로그인 하여 ls명령 실행>
ssh id@myserver ls
< ssh키를 등록해놓았을 때는 id는 생략하고 로그인 절차 없이 바로 실행, ;로 구분하여 여러 명령 실행>
ssh myserver "ls -la;df"
그러면 여러줄의 명령이나 특정 쉘스크립트,Perl스크립트 등등을 원격서버에 실행 시키면 어떻게 해야 할까? 간단한 쉘명령이야 ;로 나눠서 한 줄에 넣어서 실행하면 되지만 작업이 복잡해지면 그런 형태로는 한계가 있다. 그럴때는 다음과 같은 방법을 쓸 수 있다.
< HEREDOC을 사용하는 방법>
ssh myserver < < \EOF
ls -la
df
EOF
< 별도의 쉘스크립트를 만들고 원격에 스크립트 해석기를 실행시키고 파이프나 리다이렉션으로 보내는 방법>
#!/bin/sh
ls -la
df
가 test_script.sh 이라고 하면
cat test_script.sh | ssh myserver sh
또는
ssh myserver sh < test_script.sh
< Perl 스크립트를 ssh를 통해 실행>
cat perl_script.pl | ssh myserver perl
또는
ssh myserver perl < perl_script.pl
이것을 기초로 여러 서버에 명령을 내리려면 다음처럼 서버의 리스트를 만들고 리스트에 대해 루프를 돌면서 위의 명령을 서버별로 실행하면 될 것이다.
< 여러 서버에 루프를 돌면서 지정한 스크립트를 실행하는 스크립트>
#!/bin/sh
SERVERS="
myserver1
myserver2
"
for m in $SERVERS
do
ssh $m sh < test_script.sh
done
이렇게 하면 문제는 순차적으로 실행을 하기 때문에 한 서버씩 실행이 끝날 때 까지 기다려야 해서 속도가 늦고 나중에 결과를 보기가 힘들다는 것이다.
그러면
ssh $m sh < test_script.sh
줄을 다음과 같이
ssh $m sh < test_script.sh > $m.log &
고치면 각 ssh 명령이 fork되어서 백그라운드로 돌고 각 서버에 대한 결과는 서버이름.log 파일로 남게 된다. ( 작업결과는 *.log 파일들에 대해 grep이나 기타 유틸리티로 일괄적으로 확인 가능할 것이다. )
발췌 URL:
http://209.85.173.132/search?q=cache:yXBNexjGI0QJ:aero.dnip.net/blog/2008/11/ssh.html+ssh+%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8&cd=11&hl=ko&ct=clnk&gl=kr&client=firefox-a
파이프(pipe)란 하나의 프로세스로부터 데이터 흐름을 다른 프로세스로 연결
#include < stdio.h>
FILE *popen(const char *command, const char *open_mode);
open_mode 멤버: r 출력 읽기, w 출력 보내기(반환값 NULL 실패)
int pclose(FILE *stream_to_close); => popen이 종료할 때 까지 기달렸다가 종료시킴
POPEN 예:
#include < unistd.h>
#include < stdlib.h>
#include < stdio.h>
#include < string.h>
int main()
{
FILE *read_fp;
char buffer[BUFSIZ + 1];
int chars_read;
memset(buffer, '\0', sizeof(buffer));
read_fp = popen("cat ./popen.c | wc -l", "r");
if(read_fp != NULL)
{
chars_read=fread(buffer, sizeof(char), BUFSIZ, read_fp);
while(chars_read > 0)
{
buffer[chars_read - 1] = '\0';
printf("Reading:-\n %s\n", buffer);
chars_read = fread(buffer, sizeof(char), BUFSIZ, read_fp);
}
pclose(read_fp);
exit(EXIT_SUCCESS);
}
exit(EXIT_FAILURE);
}
결과는
[root@waf cstudy]# ./popen
Reading:-
27
저수준의 파이프(pipe) => 쉘 호출을 사용하지 않음
#include < unistd.h>
int pipe(int file_descriptor[2]);
pipe 실습 예: 681페이지 참조
포크와 exec와 pipe 실습 예: 685페이지 참조
명명된 파이프(named pipe): FIFO 예: 696페이지 참조(CPU 리소스에 가장 효율이 좋다)
고급 주제: FIFO를 사용하는 클라이언트/서버 예: 703페이지 참조
실제 응용프로그램에서는 sleep를 하지 않음
실제 응용프로그램 DB 클라이언트/서버 예: 712페이지 참조
실제 응용프로그램 DB 검색 예: 720페이지 참조
2009년 3월 15일 일요일
피드 구독하기:
댓글 (Atom)
댓글 없음:
댓글 쓰기