나는 쉘 스크립트가 스크립트 호출 방법을 변경하지 않고 모든 출력을 외부 파일에 기록 stdout
하고 stderr
각 줄(및 몇 가지 추가 항목)에 타임스탬프를 추가하기를 원합니다. 출력 리디렉션은 스크립트 자체 내에서 발생해야 합니다. 또한 스크립트나 파이프라인 명령의 기존 코드를 개별적으로 변경해서는 안 됩니다. 이상적으로는 스크립트에 몇 줄만 추가하면 됩니다.
다음 두 가지 답변을 사용하세요.
Bash에서 실행할 수 있는 지점에 도달했습니다.
#! /usr/bin/env bash
CUSTOM_PREFIX1="FancyScript"
CUSTOM_PREFIX2="SomeRunID_12-3-4.5"
LOG_FILE="/var/log/script.log"
touch $LOG_FILE
exec 1>> >(while IFS= read -r line; do printf '[%s] %s %s: %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "${CUSTOM_PREFIX1}" "${CUSTOM_PREFIX2}" "${line}"; done >> "${LOG_FILE}")
exec 2>&1
# Script continues...
d
echo "Hello"
위 스크립트를 실행하면 출력이 생성되지 않고 다음 로그 파일이 생성됩니다.
# cat /var/log/script.log
[2022-02-23 03:11:45] FancyScript SomeRunID_12-3-4.5: Development/shell_log.sh: line 12: d: command not found
[2022-02-23 03:11:45] FancyScript SomeRunID_12-3-4.5: Hello
지금까지는 괜찮았지만 두 가지를 바꾸고 싶습니다.
sh
Bash에 의존하지 않고 POSIX 쉘( )에서 작동하도록 만드세요 . 보통sh
싫어함exec 1>> >(...)
(while IFS= read ....)
나는 이것을 가장 오래된 자식 프로세스가 아닌 스크립트 자체 내의 함수로 파이프하고 싶습니다. 그것은 마치pipe_log() {...}
답변1
제 생각에는logger
이 목적을 위해 특별히 작성되었습니다: 시스템 로그 파일에 쓰기.
자세한 내용은 유틸리티 logger(1)
매뉴얼( man logger
)과 위의 POSIX 사양 링크를 참조하세요.
답변2
최대고급의Unix 도구 상자의 텍스트 처리 유틸리티는 ex
/ vi
및 awk
이며 m4
둘 다 1970년대부터 사용되었습니다. 그들 중 누구도 시간 형식 지정 기능을 갖고 있지 않습니다(POSIX를 사용하면 awk
epoch 시간을 얻을 수 있고 srand()
awk 또는 vi의 여러 구현에는 확장으로 시간 형식 지정 기능이 있지만).
perl
그러나 POSIX는 1980년대 중반부터 매우 보편화되었으며 구현이 하나만 있기 때문에 POSIX는 표준화에 참여할 필요가 없습니다.
따라서 언제든지 sh
스크립트를 다음으로 래핑할 수 있습니다.
{
your-script here
} 2>&1 | perl -MPOSIX -pse '
$_ = strftime("[%Y-%m-%dT%T%z]", localtime) . " $prefix$_"
' -- '-|=1' "-prefix=$CUSTOM_PREFIX" >> /path/to/file.log
각 행에 타임스탬프를 추가합니다.
이러한 타임스탬프 는 %z
명확하고 사후 처리가 가능합니다.
답변3
위에서 언급 한 내용은 logger
이전 시스템 로깅 환경에 대한 것입니다. 최신 시스템 기반 시스템에서는 이 systemd-cat
유틸리티가 더 적합합니다.
echo 'my message' | systemd-cat -p info -t /path/to/script/executing/this