(비공개 소스) 공급업체별 빌드 도구(FPGA 레이아웃 도구인 Microsemi Designer)를 사용하고 있습니다. 쉘 스크립트에서 호출합니다(매우 단순화됨).
... # Setup
/opt/.../designer SCRIPT:my_script.tcl |tee build.log
... # Postprocessing
문제는 designer
프로세스가 종료된 후에도 tee
프로세스가 계속 실행되어 스크립트가 계속 실행되지 않는다는 것입니다.
내가 이해하는 한, 이는 designer
수명이 긴 데몬인 을 생성
windu_scmd50
하고 해당 데몬이 (에서 상속받은 designer
) 표준 출력을 닫지 않기 때문입니다. 따라서 tee
결코 오지 않는 표준 입력(파이프에 연결됨)에서 EOF를 기다리고 있습니다.
이것이 문제의 원인이라는 증거:
ps
tee 프로세스는 계속 실행 중이지만 디자이너 프로세스는 실행되지 않음을 보여줍니다.windu_scmd50
프로세스를 종료하면tee
즉시 종료되고 스크립트가 계속됩니다(그러나 프로덕션에서는 이 작업을 수행할 수 없습니다).designer
의 출력을 totee
(또는 다른 것으로 파이프하지 않으면 incat
대신에 동일한 일이 발생함tee
) 스크립트가 중단되지 않습니다.designer
출력을 파일로 파이핑하지 않고 Jenkins에서 실행하면 Jenkins는 "프로세스 유출 파일 설명자"를 알려줍니다.이 도움말 페이지(분명히 Jenkins는 이 상황을 명시적으로 다루고 있습니다).
그래서:tee
프로세스가 종료될 때(또는 그 직후에) 프로세스가 종료 되도록 하려면 어떻게 해야 합니까 designer
?
내가 고려한 몇 가지 접근 방식은 다음과 같습니다.
- 실행 중인 프로세스의 stdout을 리디렉션할 수 있나요?
- 프로세스 종료를 감지하는 쉘 파이프 대신 사용할 수 있는 도구가 있습니까
designer
?
가능하지 않은 일부 접근 방식은 다음과 같습니다.
- 프로세스 의 출력을 무시할 수 없습니다
designer
. 로그 파일에 기록해야 합니다. windu_scmd50
해당 프로세스는 컴퓨터의 다른 프로세스에서 사용될 수 있으므로 종료할 수 없습니다 .- 에 설명된 해결 방법젠킨스 도움말 페이지의 출력도 침묵시키기 때문에 적용되지 않는 것 같습니다
designer
. windu_scmd50
실행 파일을 래퍼로 대체하기 위해 도구 설치를 수정할 수 없습니다 .
추가 참고사항:
- 프로세스 의 출력을 로깅
windu_scmd50
하는 것이 좋지만 필수 사항은 아닙니다. 그러나 디자이너 프로세스의 출력을 기록해야 합니다. - 실제로
designer
는 와 사이에tee
타임스탬프를 추가하는 또 다른 필터가 있습니다(designer ... |ts -s |tee build.log
). - 특정 기능을 사용하는
bash
것은 허용됩니다. 와의 호환성은sh
필수 사항이 아닙니다.
다음은 문제를 보여주는 최소한의 예입니다( test.sh
).
#!/bin/bash
echo "Start"
sleep 10 & # Background process that does not close stdout
echo "End"
이 스크립트를 직접 호출( ./test.sh
)하면 "Start"와 "End"가 인쇄되고 즉시 완료됩니다. 출력을 다른 프로세스( ./test.sh |cat
)로 파이프하면 "Start" 및 "End"가 즉시 인쇄되지만 완료되기 전에 10초 동안 일시 중지됩니다.
답변1
매우 간단한 해결 방법은 프로세스가 종료된 후 스트림에 메시지를 삽입하는 것입니다 designer
. cat
앞의 -like 필터는 메시지 tee
를 발견할 때 종료되어야 합니다.
다음과 같습니다.
{ /opt/.../designer SCRIPT:my_script.tcl; echo message; } \
| sed -n '/^message$/q;p' | tee build.log
노트:
designer
(또는 표준 출력을 상속하는 모든 것이) 메시지를 인쇄하면 조기sed
에 종료됩니다. 을 선택하세요sTr1ng_Unlik3ly t0-Be enCOUnTered_in vvhat designer PRinT5
. ASCII EOT 문자(8진수 004)를 선택하는 것이 좋습니다.
{ …; printf '\004\n'; } | sed -n "/^$(printf '\004')\$/q;p" | …
처리할 수 있는 것에는 한계가 있습니다
sed
. 보다이 답변은grep
, 와 비슷합니다sed
.^message$
만을 포함하는 전체 줄과 일치합니다message
. 이는 프로세스의 출력(있는 경우)이designer
개행 문자로 끝나는 것으로 가정합니다(즉, 마지막 줄이 완료되었습니다. 참조).선대불완전한 줄); 그래야만message
자체 라인에 있게 됩니다.designer
확실하게 불완전한 라인을 생성 한다면 당신은sed -n '/message$/{s/message$//;p;q};p'
. 어느 쪽이든 가능하다면 원하는 것입니다sed -n '/^message$/q;/message$/{s/message$//;p;q};p'
. 불완전한 행은designer
완전한 행이 됩니다.침묵하지 않는 후손이
designer
방해할 수 있음:message
전체 라인을 출력하려고 시도하더라도 중간 라인이 나타날 수 있습니다 . 우리에게는 마치 불완전한 줄이 생성된sed
것처럼 보일 것입니다 .designer
- 선택한 메시지가 매우 길면 다른 데이터와 함께 인터리브된 파이프에 나타날 수 있습니다(참조이 답변그리고
PIPE_BUF
여기). 그러한 경우 우리는sed
그것을 전혀 감지하지 못할 것입니다.