백그라운드에서 처리하는 동안 여러 파일에 로깅(nohoup)

백그라운드에서 처리하는 동안 여러 파일에 로깅(nohoup)

두 개의 로그 파일에 병렬로 기록하는 bash 스크립트가 있습니다.

echo "$(date) | [STATE] Activating IP forwarding" >> $logsPath$logFileName
echo $(date +"%Y-%m-%d %H:%M")","$previousState >> $logsPath$usageStatsFileName
echo $(date +"%Y-%m-%d %H:%M")","$currentState >> $logsPath$usageStatsFileName

스크립트를 포그라운드에서 실행하면 제대로 작동하지만 백그라운드로 보내면 이 파일에 아무 것도 기록되지 않습니다.

nohup nice ./rfid_reader.sh&

백그라운드에서 스크립트를 실행하고 위 두 파일의 로그를 계속 유지하려면 어떻게 해야 하는지 힌트를 주실 수 있나요?

답변1

중요한 팁:

이것은 거의 확실하게 질문과 관련이 없습니다. 다른 사람들에게 도움이 될 수 있기 때문에 여기에 남겨두겠습니다. 하지만 적어도 제가 사용하는 nohup데비안 버전에서는 내부 리디렉션이 영향을 받지 않고 nohup스크립트의 stderr 및 stdout만 캡처됩니다.


기본적으로 nohup모든 출력은 에 인쇄됩니다 nohup.out. 일반적으로 이를 알리지만 백그라운드에서 실행 중이므로 볼 수 없습니다. 예를 들어 다음을 시도해 보세요.

$ nohup echo "foo"
nohup: ignoring input and appending output to ‘nohup.out’

이를 방지하려면 프로그램 출력을 명시적으로 리디렉션해야 합니다.

$ nohup echo "foo" > bar
nohup: ignoring input and redirecting stderr to stdout

따라서 스크립트를 실행하고 해당 출력을 리디렉션해야 합니다. 표준 오류와 표준 출력 스트림은 모두 동일한 파일로 리디렉션됩니다.

nohup nice ./rfid_reader.sh > output_file &

이는 실제로 nohup의 합리적인 기본값입니다. 전체 목적은 터미널 세션을 닫고 백그라운드에서 실행되도록 하는 것이므로 터미널에 인쇄하면 그 목적이 무산되기 때문입니다.

답변2

넌 정말 필요 없어nohup알잖아. 사실 저는 개인적으로 그 용도를 찾지 못했습니다.

( ./rfidreader.sh 1>&2 & ) 2>&- &

이렇게 하면 프로세스가 터미널에서 분리되고, 해야 할 일을 계속 수행하며 문제가 발생하는 것을 방지할 수 있습니다.

데모 스크립트

cat <<-\DEMO >|${s=/tmp/script} 
printf 'tty is %s\nparent pid is %s\npid is pid=%s\n' \
     "$(tty)" "$PPID" "$$"
exec 1>&2 ; nums=$(seq 0 9)
rm ${files=$(printf "/tmp/file%s\n" $nums)}
for n in $nums ; do { for f in $files ; do
    echo "Line $n" >>"$f" ; done
sleep 1 ; } ; done
#END
DEMO

데모 실행

s=/tmp/script ;chmod +x $s ;info="$(($s &)2>&- &)"
echo "$info" ; pid="${info##*=}" ; echo
while ps -p $pid >/dev/null ; do sleep 3 ; done
for f in /tmp/file[0-9] ; do
    printf 'path : %s\tline count : %s\n' \
        $f $(<$f wc -l)
done

산출:

tty is not a tty
parent pid is 1
pid is 12123

path : /tmp/file0    line count : 10
path : /tmp/file1    line count : 10
path : /tmp/file2    line count : 10
path : /tmp/file3    line count : 10
path : /tmp/file4    line count : 10
path : /tmp/file5    line count : 10
path : /tmp/file6    line count : 10
path : /tmp/file7    line count : 10
path : /tmp/file8    line count : 10
path : /tmp/file9    line count : 10

위에서 증명되었습니다. 라는 파일을 빌드하고 실행합니다./tmp/script, chmod~의실행 파일로 제공되며 다음과 같은 형식으로 제공됩니다.&background중 하나&backgrounded ( subshell ).

스크립트rms /tmp/file0-910개 파일 및echoes초당 하나의 행이 10명 모두에게 전달됩니다. 내가 좀 잡았어$info거부로부터 흘러 나와 제시된다.$(command substitution). While ps아직 보고 중$pid캡처했는데 아직 실행 중이라는 걸 알고 있으므로sleep.완료되면 10개 파일 모두의 행이 계산됩니다.wc.

이런 방식으로 프로세스를 호출한 후에는 원래 상위 프로세스를 자유롭게 닫을 수 있으며 계속 실행됩니다. 사실상 거부됩니다.

프로세스가 실제로 시작되었다는 점은 언급할 가치가 있다고 생각합니다.$(command substitution)그리고printfs내 거$info이런 식으로 효과적으로 제어할 수 있기를 바랍니다. 하지만 일단 터미널 출력이 떨어지면exec 1>&2( 와 동일한 서브쉘에서 닫힘 2>&-),프로세스가 종료되고 다른 쪽에서 이를 기다려야 합니다. 특히 모든 리디렉션과 프로세스 리더에 집중할 수 있는 한 입력 파이프를 처리하는 데 사용하는 경우 두 세계 모두에서 최고입니다.

다른 모든 것은 여기서 시연을 위한 것입니다. 이를 실행하는 데 필요한 것은 최상위 스크립트와 다음뿐입니다.

info="$(($script_path &)2>&- &)"    

노트:이것은 내가 보여주고 싶은 내용만을 터미널에 인쇄할 것입니다. 지적한대로$PPID,프로세스가 터미널에 의해 거부되었으며 이 프로세스의 직계 하위 프로세스입니다.$PID 1.

답변3

모든 사람의 답변에 감사드립니다. 나는 그들로부터 많은 것을 배웠습니다. 문제가 해결되었습니다. Nohoup은 외부 파일에 대한 로깅을 방해하지 않습니다. 내 문제의 원인은 임베디드 Linux를 사용하고 있기 때문에 시스템 성능일 가능성이 높습니다. 무엇을 해야할지 모르겠어서 시스템을 다시 시작하고 백그라운드에서 스크립트를 다시 시작했습니다. 이제 괜찮아.

문제는 어떻게든 해결됐는데 왜 재부팅이 필요한지 의문이었습니다.

관련 정보