현재 쉘 스크립트가 동시 로깅 할 때마다 왜 실패하는지 파악하려고합니다. 한 번씩 동안이 구문 오류와 함께 실패 지금bash 스크립트의 동시 로깅
log()
{
local l_text=$1
local l_file="/path/to/logs/$(date +%Y%m%d)_script.log"
local l_line="$(date +'%Y-%m-%d %H:%M:%S') $(hostname -s) ${l_text}"
echo ${l_line} >> ${l_file}
}
: 나는 여러 하위를 가지고
/path/to/script.sh: command substitution: line 163: syntax error near unexpected token `)'
/path/to/script.sh: command substitution: line 163: `hostname -s) ${l_text}'
문제가있다
나는 다음과 같은 쉘 기능이 프로세스는 각각 로그를 남기고 트랩을 보냅니다 (로깅이 수행되는 동안). 나는 문제를 디버깅하고 함수가 동시에 세 번 입력되었을 때이를 발견했다. 먼저 main
프로세스가 입력되고 child
이 입력됩니다. date
부분이 l_text
이 실행 된 후 main
get이 에 의해 중단되었으므로 child
이 발생하고이 trap
에서 로그를 시도합니다. child
과 trap
은 로깅을 끝내지 만, main
이 트랩 후 재개되어 hostname
부분 (추정치)을 실행하려고 시도하고이 오류로 실패합니다.
따라서 main
은 로그 문 일부에 $(date +'%Y-%m-%d %H:%M:%S') $(hostname -s) ${l_text}
부분을 생성하는 동안 잠자기하는 것을 좋아하지 않으므로 다시 시작할 수 없습니다. 로컬 변수와 스레드 안전 출력 메소드를 사용하고 있기 때문에 정상적으로 작동한다고 가정합니다.
여기서 내가 실행하고있는 일반적인 동시성 문제입니까? 또는 이것은 bash 스크립트의 트랩 메커니즘에 매우 특정한가요? C에서 SIGNAL 처리의 필수 항목을 알고 있으므로 SIGNAL 처리기에서만 특정 작업 만 허용된다는 것을 알고 있습니다. 그러나 bash 스크립트에서 SIGNAL을 처리 할 때도 동일한 예방 조치가 적용되는지는 잘 모릅니다. 나는 이것에 대한 문서를 찾으려고 노력했지만, 찾을 수있는 문서가 없기 때문에 스크립트에서 SIGNAL 처리와 관련된 문제를 지적했다.
편집 :
#!/bin/bash
log() {
local text="$(date +'%Y-%m-%d %H:%M:%S') $(hostname -s) $1"
echo $text >> /dev/null
}
sub_process() {
while true; do
log "Thread is running"
kill -ALRM $$
sleep 1
done
}
trap "log 'received ALRM'" ALRM
sub_process &
sub_process_pid=$!
trap "kill ${sub_process_pid}; exit 0" INT TERM
while true; do
log "Main is running"
sleep 1
done
가끔씩이 스크립트 때문에 구문 오류에 살해 얻을 것이다 : 여기
문제를 복제하는 데 사용할 수있는 실제로 사용 간단한 스크립트입니다 라인 5는 echo $text >> /dev/null
이지만, 구문 오류가 hostname 명령을 언급했기 때문에 위에 게시 한 명령과 유사합니다. 또한 by-by-one 오류가 있다고 가정하고 실제 오류는 4 행에 있습니다. local text="$(date +'%Y-%m-%d %H:%M:%S') $(hostname -s) $1"
입니다.
누구든지 위의 스크립트로 해결하려면 무엇을해야합니까? 나는 약간의 임시 변수에 문자열의 건설을 이동 시도을 벌써 :
log() {
local thedate=$(date +'%Y-%m-%d %H:%M:%S')
local thehostname=$(hostname -s)
local text="${thedate} ${thehostname} $1"
echo $text >> /dev/null
}
이 방법을 오류가 자주 나타납니다,하지만 여전히 존재하는, 그래서 이것은 진짜 수정하지 않습니다.
'='주위의 공백 문자는 불법입니다. – kojiro
@kojiro : 힌트를 주셔서 감사합니다 ... 공백 문자는 원본에 없습니다. 나는 코드를 좋은 예로 줄이면 실수로 그것을 도입했습니다. 나는 이것을 편집 할 것이다. – LiKao
'thread'라는 이름은 여기 오해의 소지가 있습니다. bash는 쓰레드가 아닌 서브 프로세스를 사용합니다 ...'trap '에'$?'대신'$!'를 쓰고 싶습니다. $ ?; exit 0 "INT TERM' 그리고 'INT' /'TERM' /'ALRM'은'SIG' ('SIGINT')가 누락되었습니다. –