조건부 실행은 Bash에서 하위 프로세스의 종료 상태에 따라 스크립트 흐름을 제어하는 데 사용됩니다. 그러나 어떤 경우에는 하위 프로세스(애플리케이션)가 대화형 목적으로 백그라운드에서 실행되므로 종료되지 않고 닫힐 때까지 종료 상태가 없습니다.
PDF 뷰어 실행과 같은 몇 가지 예를 고려해보세요.도포프. example.pdf 파일이 존재하는 첫 번째 경우를 생각해 보십시오.
$ mupdf example.pdf &
[1] 16220
작동하므로 조건부 실행을 시도해 보겠습니다.
$ mupdf example.pdf & && echo TRUE
bash: syntax error near unexpected token '&&'
음. 자, 오류를 피하기 위해 다른 (인공적인) 접근 방식을 시도해 보겠습니다.
$ if mupdf example.pdf &; then echo TRUE; fi
bash: syntax error near unexpected token ';'
어때요?
$ if (mupdf example.pdf &); then echo TRUE; fi
TRUE
이는 유망해 보이지만 존재하지 않는 파일을 사용하여 두 번째 경우를 시도해 보겠습니다.
$ mupdf nofile.pdf &
[1] 16282
$ error: cannot open nofile.pdf
error: cannot load document 'nofile.pdf'
mupdf: error: cannot open document
$ if (mupdf nofile.pdf &); then echo TRUE; fi
TRUE
$ error: cannot open nofile.pdf
error: cannot load document 'nofile.pdf'
mupdf: error: cannot open document
그 구조도 작동하지 않습니다. 따라서 종료 상태가 없기 때문에 일반적인 조건부 실행 접근 방식이 작동하지 않습니다. 그러나 성공한 경우와 실패한 경우 모두 처음에 pid가 생성된다는 것을 알았습니다(도포프두 번째 경우에는 열 수 없습니다. 결국 시작이 실패합니다.
그래서 다른 접근 방식을 시도하고 배경 PID에 어떤 일이 일어나는지 기다리면서 다음 스크립트를 작성했습니다.
#!/usr/bin/env bash
# usage: ./show <file>.pdf
mupdf "$1" &>/dev/null &
sleep 2
if kill -0 $! &>/dev/null
then
echo TRUE
else
echo FALSE
fi
# end file
그리고 첫 번째 경우를 테스트해 보세요.
$ ./show example.pdf # case 1
[1] 16602
TRUE
그것은 중요하지 않습니다. 이제 두 번째 경우는 다음과 같습니다.
$ ./show nofile.pdf # case 2
[2] 16699
[2]+ Exit 1 mupdf nofile.pdf &> /dev/null
FALSE
글쎄, 그것도 작동합니다. 하지만 이는 프로세스를 확인하는 매우 복잡한 방법인 것으로 보이며, 시작하는 데 시간이 더 걸리면(2초 이상) 실패할 수도 있습니다. 그래서 제 질문은 이 문제를 해결하는 더 나은(더 깨끗한) 방법이 있습니까?입니다.
답변1
이 주제와 유사한 주제를 많이 찾았습니다. 다음을 사용해 보세요.xdo 도구그리고제어판영구 창 응용 프로그램이나 기타 영구 하위 프로세스의 시작을 테스트하는 데 사용됩니다. 그러나 이것을 사용하는 것은 불필요한 복잡해 보입니다. 아래 솔루션을 사용하면 영구 하위 프로세스를 조건부로 실행할 수 있습니다. 0.5초의 수면 시간을 활용합니다. 관심 있는 하위 프로세스를 성공적으로 시작하는 데 시간이 더 오래 걸리는 경우 이에 따라 이 기간도 늘려야 합니다.
배쉬 소스 파일방사
#/usr/bin/env bash
# launch : will allow launching a windowed application or persistent
# sub-process in the background so that conditional execution can be
# applied to determine whether or not it has launched successfully -
# dependencies: GNU coreutils (sleep), util-Linux (kill)
# usage: ./launch process arg_1 .. arg_n && echo TRUE || echo FALSE
$@ &>/dev/null & sleep 0.5 && kill -0 $! 2>/dev/null
# end file
하도록 하다:
$ ./launch mupdf example.pdf && echo TRUE || echo FALSE
TRUE
$ ./launch mupdf nofile.pdf && echo TRUE || echo FALSE
FALSE
이 정보에 대한 후기로서 다음 제안 사항을 포함하는 것이 유용할 것이라고 생각했습니다.맥사이프오프닝 기사에 대한 댓글입니다.
위의 구성이 현재 작업을 달성한다는 점을 고려하면,맥사이프이를 지적하면 신호를 호출 스크립트에 전파하지 않고 무시하고 삭제하기 때문에 다른 문제가 발생할 수 있습니다. 이것은 매우 중요한 관찰입니다.
신호는 프로세스 간 통신의 핵심 요소이며 이벤트 중심 스크립팅의 가능성으로 이어질 수 있습니다. 따라서 보다 강력하고 효율적인 스크립트를 위해서는맥사이프신호가 전파될 수 있도록 신호를 캡처하려면 다음 방법을 권장합니다.
{ mupdf some.pdf || kill -"$(($?&127))" "$$"; } &
1에서 128개의 가능한 신호(POSIX)를 조작할 수 있는 $?&127
데비안 시스템에는 64개가 있으므로 신호 마스크를 $?&63
대신 사용할 수 있습니다.
따라서 결론적으로 프로세스 간 통신에 관심이 없는 매우 간단한 스크립트의 경우 권장됩니다.방사유용할 수 있지만 더 많은 경우, 특히 프로세스 간 통신이 중요한 경우 제안된 대로 신호를 포착(및 전파)합니다.맥사이프.
답변2
한 줄로:
mupdf example.pdf & echo mupdf is now in the background; wait $! && echo FINISHED successfully