다음 코드 조각을 작성하려고 합니다. 디자인 목표는 스크립트의 모든 출력을 기록하는 것이며 래퍼가 되어서는 안 됩니다. 줄이 적을수록 좋습니다.
(이 단계에서는) 사용자 입력에 관심이 없으며 대상 스크립트는 비대화형으로 실행됩니다.
이 조각에는 다음이 필요합니다.
- 로그에 stdout을 출력하고 항상 콘솔에 에코됩니다.
- 디버깅이 활성화된 경우 stderr을 로그로 출력하고 콘솔에 에코합니다.
- stderr 메시지에는 타임스탬프와 기타 유용한 접두사가 있어야 합니다.
현재 최신 버전의 bash(4.2+?)에서만 테스트된 다음이 있습니다. 예를 들어 Ubuntu에서는 잘 작동하지만 CentOS6에서는 제대로 작동하지 않습니다.
DEBUG_LOG="${0##*/}.log"
# copy stdout to log always and echo to console
exec > >(tee -a ${DEBUG_LOG})
# copy stderr to log only, unless debugging is enabled
[ $DEBUG_TEST = "true" ] \
&& exec 2> >(tee -a ${DEBUG_LOG} >&2) \
|| exec 2>> ${DEBUG_LOG}
그래서 이거...
# Expand escaped characters, wrap at 70 chars on spaces,
# and indent wrapped lines
msg_log() {
echo -e "$(date +%T) ${0##*/}: $1" \
| fold -w70 -s | sed '2~1s/^/ /' >&2;
}
msg_con() {
if [ "${DEBUG_TEST}" = "true" ]; then
msg_log "$1"
else
echo -e "$1" | fold -w70 -s | sed '2~1s/^/ /';
fi
}
echo
예를 들어 이러한 msg 프로시저 중 하나를 호출 할 수 있습니다 msg_con "hello world"
.
또한 스크립트 출력은 호출 시 설정된 환경 변수(예 DEBUG_TEST=true myscript
: .
일부 셸(비지박스 등)에서는 exec가 작동하지 않을 수 있다는 내용을 읽었습니다. mkfifo와 포크 조합이 있습니다https://stackoverflow.com/a/5200754비슷한 일을 했지만 꼭 필요한 경우가 아니면 포크를 사용하지 않는 것이 좋습니다.
bash 예제를 선호하세요. 하지만 sh에서 작동하는 것이나 이식성이 더 좋은 것이 더 좋을 것입니다. 어떤 아이디어가 있나요?
답변1
function startLogging {
exec > >(gawk -v pid=$$ '{ print strftime("%F-%T"),pid,$0; fflush(); }' | tee -a $logfile)
[ ! -z "$DEBUG" ] && exec 2>&1 || exec 2> >(gawk -v pid=$$ '{ print strftime("%F-%T"),pid,$0; fflush(); }' >>$logfile)
echo "=== Log started for $$ at $(date +%F-%T) ==="
}
$logfile을 뭔가로 설정해야 합니다
답변2
exec > filename
sh에서 작동해야 하며 실제로는 busybox v1.15.3(2011년 11월)에서 작동합니다. 그러나 프로세스 교체는 >(command)
bash 확장이므로 이식성이 없습니다. 스크립트에서는 사용하지 마십시오. 왜 >>
충분하지 않습니까?
exec 1>>${DEBUG_LOG}
exec 2>>${DEBUG_LOG}
또 다른 해결책은 스크립트 외부에서 리디렉션을 지정하는 것입니다. 스크립트가 백그라운드에서 호출될 때(cron 또는 시스템 스크립트 등을 통해) 다음과 같이 호출되어야 합니다.
./my_script 1>>${DEBUG_LOG} 2>>${DEBUG_LOG}
스크립트를 수동으로 호출하고 출력을 보려면 리디렉션하지 않고 호출하면 됩니다.
답변3
이 두 가지 예는 귀하가 언급한 내용을 달성할 것입니다
echo -n $(date) >> $DEBUG_LOG
command 2>&1 | tee -a $DEBUG_LOG
또는
echo -n $(date) >> $DEBUG_LOG
command >> $DEBUG_LOG 2>&1
답변4
tee
명령이나 명령을 사용할 수 있으며 script
둘 다 매우 유용합니다.