[쉘 스크립트] if 문에서 실행되는 커맨드를 백그라운드로 돌리기
글쓴이: dmr0923 / 작성시간: 목, 2014/01/16 - 11:32오전
안녕하세요.
리눅스 쉘 스크립트를 작성 중에 궁금한 점이 있어 글을 올리게 되었습니다.
if [ of command] 형식을 사용할 경우 커맨드를 백그라운드로 돌리고자 하는데 문법이 약한지 계속 포그라운드로 동작하네요..
예를 들면,
varRec="/opt/ipnc/rec" # 커맨드 if ! $varRec 인자1 인자2 &; then echo "Error.." exit 1 fi
if 문에 넣지 않고 한줄짜리로 하면 포그라운드로 잘 동작합니다($varRec 인자1 인자2 &)
구동환경은 임베디드 리눅스(우분투) 입니다.
호스트 PC 에서 코딩을 작성한 후 타깃보드에서는 이를 nfs 로 끌어와 sh script 형식으로 실행시켰습니다.
Forums:
쉘스크립트에서 돌린 백그라운드 프로세스의 종료값을
쉘스크립트에서 돌린 백그라운드 프로세스의 종료값을 알기 위해서는 wait 명령을 이용하면 됩니다.
사용법은 man wait 하시면 상세히 나와 있습니다.
예로 드신 것처럼 if 문에서 바로 커맨드를 백그라운드로 실행시키고, 종료값을 사용하려는 것은 의미없는 행위입니다. 일일이 설명하지 않아도 조금 생각하면 아실 거라고 생각합니다.
쉘스크립트에서 백그라운드로 어떤 커맨드를 실행시킨 후, 다른 작업을 하다가 필요한 시점에서 wait 명령을 이용해 커맨드의 종료값을 이용하는 식으로 구성하셔야 하지 않을까요.
참고로 잠시 살펴보니 wait cmd_pid 하는
참고로 잠시 살펴보니 wait cmd_pid 하는 시점에서 백그라운드 커맨드가 이미 종료된 상태에서일지라도 에러를 내지 않고 이미 종료된 백그라운드 커맨드의 종료값을 알려줍니다. 아직 종료되지 않았다면 기다렸다가 알려주고요.
답변 감사드립니다. 정확히 이해는 못하고 있지만..
답변 감사드립니다.
정확히 이해는 못하고 있지만.. if 문에서는 커맨드의 종료상태를 받아와서 판단해야 하는데.. 백그라운드로 계속 돌아가는 커맨드를 넣는다는게 논리적으로 맞지 않은 것 같더군요. 말씀 주신대로 구조를 변경해서 다시 한번 도전해보고 있습니다!!
백그라운드로 실행시키는 작업은 시스템 메모리가
백그라운드로 실행시키는 작업은
시스템 메모리가 모자라든가 하는 OS 측면의 이유가 아니면 거의 성공하겠지요...
그러니 $? 로 확인해봐도 거의 99% 성공메시지인 0이 나옵니다..
설령 백그라운드로 실행될 프로그램이 잘못 만들어져서 실행됐다가 곧바로 죽어버린다고 하더라도
백그라운드로 실행 자체는 성공했기 때문에 0이 나오죠..
전 그래서 백그라운드로 실행 후 프로그램이 제대로 동작하지 않았으면 바로 프로세스가 종료가 되어버릴 테니까
ps -ef | grep 프로그램명 | awk '{print $2}' 으로 프로세스 리스트에서 제대로 동작하고 있는가를 확인합니다..
백그라운드 커맨드의 pid를 $!로 받아서, 이후에
백그라운드 커맨드의 pid를 $!로 받아서, 이후에 kill -0 pid 명령의 종료값이 0인지 확인하는 방법으로 커맨드가 아직 실행되고 있는지, 종료되었는지를 확인할 수 있습니다.
또한 ps -ef | grep 프로그램명 | grep -v grep | awk '{print $2}'를 의도하신 거겠지만, 여전히 조잡해서 그냥 'pidof 프로그램명' 을 써서 pid 리스트를 받아옵니다.
간단한 C 프로그램으로 종료값을 테스트해 보면, wait 명령어가 명확하게 프로그램의 종료값을 받아오는 것을 볼 수 있습니다. 말씀하신 "백그라운드 실행 자체는 성공했기 때문에 0이 나오죠"는 틀린 말입니다. 종료값 exit status는 말 그대로 프로그램이 의도해서 나온(return 0, exit(1) 등) 값이지 백그라운드 실행 성공여부를 요인으로 한다는 말은 틀린 말입니다.
또한 커널이 죽이거나, kill -9 pid 등 외부 요인으로 프로그램이 죽는 경우에도 종료값이 128 + 시그널번호 ( 128 + 9 = 137 등) 로 나타나기 때문에 쉽게 종료값의 출처를 확인할 수 있습니다.
$!는 알고 있습니다. kill -0 pid로
$!는 알고 있습니다. kill -0 pid로 커맨드가 실행되고 있는지 확인한다는건 좀 이상하네요. 확인을 위해 프로세서를 종료시켜 본다는 말씀인가요?
pidof 프로그램명도 알고 있습니다. 왜 굳이 ps -ef | grep 을 이용했냐면 pidof는 같은 프로그램을 다른 인자값으로 실행시켰을 경우 두 프로그램을 구분하지 못합니다.
글쓴분께서 무슨 프로그램을 실행시킬 지 알 수 없어 (만약 java로 뭔가 실행시킨다면 java -jar로 실행된 모든 프로그램의 pid가 나올겁니다.) 이 방법을 말씀드린거구요
"백그라운드 실행 자체는 성공했기 때문에 0이 나오죠"는 틀린 말입니다. 에 대해서는 직접 한번 해보신 후에 다시 말씀해주세요. 글쓴분께서 원하시는건 스크립트 레벨에서의 리턴값입니다.
그야말로 간단하게 a.sh라는 이름으로
라는 스크립트가 있을 때, sh a.sh 후에 echo $? 를 해보면 분명히 999가 나옵니다.
sh a.sh > /dev/null & 로 백그라운드로 실행시켜 본 후 echo $?를 하면 기본적으로 0의 리턴값을 가지고 부가적으로 [1]+ Exit 999 sh a.sh > /dev/null 이 붙어나오죠.
이는 c로 만들어진 프로그램에 대해서도 마찬가지입니다. 백그라운드 실행에 대해서는 프로그램의 리턴값 및 exit값으로 판단하지 않습니다.
kill 은 프로그램을 종료하는 프로그램이 아닙니다.
kill 은 프로그램을 종료하는 프로그램이 아닙니다. 주어진 pid의 프로세스에 시그널은 보내는 프로그램이라고 표현하는 것이 옳다고 생각합니다.
kill -0 pid > /dev/null 2>&1 && echo OK || echo NO
로 테스트해 보면 될일입니다. kill 명령어는 kill() 시스템 콜을 쓸 것이고, kill() 에서 0번 시그널은 프로세스의 존재 여부를 확인하는 데 사용할 수 있습니다(man 2 kill). 물론 kill 명령어는 이외에 권한 문제도 종료값에 영향을 주기에, 사용가능한 상황을 알고 사용해야 하기 때문에 추천하진 않습니다.
제 글은 메시지에 나오는 999란 값이 알고 싶다면 그걸 wait란 명령으로 잡아낼 수 있다는 거구요.
하지만, 전체적으로 글을 다시 살펴보니, 원질문자의 의도는 백드라운드로 커맨드를 실행시키고, 그 백그라운드 실행이 제대로 이루어졌지를 확인하고 싶어하는 듯 합니다. 이런 목적이라면 말씀대로 $? 값을 쓰기보다는 프로세스가 실재하는지를 확인하는 방법이 옳다는데 동의합니다. 그 방법에는 특별히 어떤 걸 고집하진 않습니다. 적절한 걸 쓰면 되지요.
프로세스가 존재하는지 확인하는 방법은 이 경우에는 백그라운드 커맨드의 pid를 알 수 있고 권한 문제가 없을것이기 때문에 제 생각에는 kill -0 pid 의 종료값을 확인하는 것이 간단한 방법이라고 생각합니다.
/proc/{cmd pid} 디렉토리의 존재 여부
/proc/{cmd pid} 디렉토리의 존재 여부 체크 등의 /proc 파일 시스템을 이용하는 방법도 있습니다.
댓글 달기