
다음과 같은 코드가 있습니다.
{
trap cleanup SIGHUP SIGINT SIGTERM
function executed() {
if [ ${1} -ne 0 ]
then
echo "Failed!"
cleanup
exit
else
echo "Succeeded!"
fi
}
function cleanup() {
echo "Cleaning up ..."
# deleting some files and stuff like that
}
bunch of code ...
...
} 2>&1 | while IFS= read -r line; do echo "$(date) $line"; done \
>> ldapfe_graceful_$(date '+%Y_%m_%d__%H_%M_%S').log
이것저것 회사의 정책을 잘 모르기 때문에 코드를 모두 붙여넣을 수는 없지만, 가장 중요한 부분은 거기에 있습니다.
이 스크립트가 실행되는 동안 Ctrl+C를 누르면 즉시 중지되거나 약간의 ^C가 표시되고 5~10초 후에 중지되지만 정리 함수는 호출되지 않습니다.
파일로 멋지게 리디렉션하기 위해 모든 코드를 {}에 넣었습니다. (이것을 호출하고 리디렉션하기 위해 별도의 스크립트를 사용하지만 스크립트를 종료하고 이 스크립트에 신호를 전파하는 것이 더 어려운 것 같아서 그냥 다음과 같이 하기로 결정했습니다. 모두 중괄호 안에 넣으세요).
트랩과 정리를 {} 블록 외부에 넣으면 정리 함수가 호출되지만 코드의 다른 부분에서도 이를 호출할 수 있어야 하기 때문에 중괄호에 대해 뭔가 빠졌다고 확신합니다. 대괄호 밖의 {} 블록 안에 있습니다.
편집: 정리 기능 후에 트랩을 선언하려고 시도했지만 변경 사항이 없습니다.
답변1
코드의 다른 부분은 실제 호출 전에 선언되는 한 {} 중괄호 내부인지 외부인지에 관계없이 정리 함수를 호출할 수 있어야 합니다(실제로 이전 스크립트 줄과 아무 관련이 없습니다). 동일하거나 더 낮은 bash 쉘 레벨(
$BASH_SUBSHELL
)에 있습니다.(수정됨) 트랩이 선언되면 호출할 수 있으며, 트랩은 동일하거나 낮은 서브쉘 레벨에서 선언되어야 합니다. 신호를 실행하면 아래 코드에 표시된 것처럼 신호가 아래쪽으로 계단식으로 배열되는 것 같습니다.
.
#!/usr/bin/env bash
trap "echo ok 0" 2
(
echo subshell: $BASH_SUBSHELL
trap "echo ok 1" 2
(
echo subshell: $BASH_SUBSHELL
trap "echo ok 2" 2;
sleep 100
#now test the trap
)
)
결과:
subshell: 0
subshell: 1
subshell: 2
^Cok 2
ok 1
ok 0
하지만 파이프는 아닙니다.
#!/bin/bash
trap "echo ok 0" 2
{
echo $BASH_SUBSHELL
trap "echo ok 1" 2
} | \
{
trap "echo ok 2" 2
read line; echo $line;
sleep 100
#now Ctrl-c
}
결과:
1
^Cok 2
ok 0
- 중괄호는 익명 함수를 구성합니다. 이 기능은 bash 쉘 수준을 유지하지만 모든 상황에서 유지되는 것은 아닙니다.
설명을 위해 아래 스크립트를 분석하세요. 터미널에서 실행하고 결과를 확인하세요.
#!/bin/bash
k=k
msg='echo line: $LINENO, \$k: $k, BASH_SUBSHELL: $BASH_SUBSHELL'
eval $msg
{
k=a
eval $msg
} &
sleep 1
#job %1 should be done by now
jobs
eval $msg
{
k=b
eval $msg
} | {
read line; echo $line;
eval $msg
}
eval $msg
{
k=c
eval $msg
}
eval $msg
{ trap 'echo -e "\nterminating"; exit;' 2;}
sleep 100 #try out the trap by hitting Ctrl-c
- 스크립트의 솔루션은 다음과 같습니다.
ㅏ. 트랩을 첫 번째 트랩보다 먼저 이동하십시오 {
.
b. 처음으로 {
일부 스마트 구성을 사용하기 전에 clean 함수를 이동해 보십시오 eval
(내 스크립트에서 어떻게 작동하는지 확인). 이것이 가능하지 않은 경우 중괄호 안에 프록시 함수를 작성하여 함수를 보다 일반적으로 만들고 트랩의 호출에서 누락된 부분을 패치해 보십시오.