Bash 스크립트에 사용되는 다음 함수를 확인하세요.
LOG_FILE="/root/collect.log";\
date_info() {
local cmd; cmd=$(basename $0)
echo "$(date --rfc-3339=seconds) $cmd.info: $*" >>"$LOG_FILE"
>&2 echo "$cmd.info: $*"
}
누군가 이 기능을 이해하도록 도와줄 수 있나요? 나는 모든 것이 path에 있는 log_file에 수집된다는 것을 알고 있지만 /root/collect.log
날짜와 시간을 제외하고 세부 사항을 이해할 수 없습니다.
감사합니다, 타이토
답변1
본질적으로 단지 로깅 기능입니다.
local cmd; cmd=$(basename $0)
이는 cmd
지역 변수로 선언되므로 이 함수 내에서만 사용할 수 있습니다. 할당된 값은 $(basename $0)
쉘 또는 쉘 스크립트의 이름으로 확장됩니다.
echo "$(date --rfc-3339=seconds) $cmd.info: $*" >>"$LOG_FILE"
여기에 날짜가 표시됩니다.rfc-3339 형식(이것은 GNU date 에만 사용 가능한 옵션일 수 있으므로 명령의 이식성이 떨어질 수 있습니다.) 다음에서 실행하면 cmd
추가되는 값은 다음과 같습니다..info:
script.sh
script.sh.info:
$*
의 첫 번째 문자로 확장된 함수에 제공된 모든 인수를 나타냅니다 IFS
.
date_info unable to do the thing
따라서 로그 파일에서 이 명령을 실행 하면 script.sh
로그 파일에 다음과 같은 줄이 표시됩니다.
2022-04-20 06:35:00-06:00 script.sh.info: unable to do the thing
마지막 줄:
>&2 echo "$cmd.info: $*"
이 줄은 stdout을 stderr로 리디렉션한 다음 기본적으로 동일한 내용(날짜 제외)을 터미널에 에코합니다.
그리고 ;\
마지막 부분은 LOG_FILE="/root/collect.log";\
좀 무의미하네요. ;
은 쉘 스크립트의 줄 바꿈 끝에 불필요한 명령 구분 기호이며 \
다음 줄 바꿈을 이스케이프합니다. 서로를 취소하고 제거할 수 있습니다.
답변2
긴 이야기 짧게
많은 잘라내기 및 붙여넣기를 통해 구축된 것처럼 보이는 로깅 기능(아마도 syslog와 유사한 항목을 생성하려고 시도함)입니다. 보다 심층적인 분석 및 재구성은 아래에 제공됩니다.
원래 게시된 코드는 무엇을 합니까?
참고: 원본 코드는 GNU 날짜(BSD 날짜는 작동하지 않음)에 의존하며 Bash에 의존할 가능성이 높습니다.중단주의유용.
다음은 다른 소스에서 복사 및 붙여넣기를 많이 수행한 사람이 작성한 Bourne 기반 스크립트입니다. 심각도가 "info"인 로그 메시지를 로그 파일에 추가하고 메시지 복사본을 표준 오류에 추가하려는 의도인 것 같습니다. 이는 제대로 작성되지 않았으며("shellcheck가 불평하게 만듭니다"로 정의됨) 여러 가지 방법으로 개선될 수 있습니다. 게시된 원본 코드는 다음과 같습니다.
LOG_FILE="/root/collect.log";\
date_info() {
local cmd; cmd=$(basename "$0)
echo "$(date --rfc-3339=seconds) $cmd.info: $*" >>"$LOG_FILE"
>&2 echo "$cmd.info: $*"
}
모두 대문자 변수는 일반적으로 내보낸 환경 변수를 의미하고 의도적으로 bashism을 피하는 것 같지 않으므로 코드는 보다 표준적인 로깅 형식, 일부 내장 Bash 확장 및 일반적으로 무엇이든 사용하려는 보다 명확한 의미를 사용하여 다시 작성할 수 있습니다. Bash의 최신 버전과 및 date
유틸리티 의 GNU 버전입니다 tr
(예: gdate
GNU gtr
유틸리티가 설치된 Darwin 시스템).
리팩터링된 원본 코드
코드와 그 의도에 대한 많은 가정을 기반으로 합니다. 그 중 일부는 원본 소스를 보는 것만으로는 수집할 수 없기 때문에 확인해야 합니다. 이것이 더 유연하고 읽기 쉬운 리팩토링이라고 생각합니다. 특정 사용 사례에 맞게 조정하려면 형식과 심각도 수준을 조정하세요.
#!/usr/bin/env bash
# Set a default logfile if one isn't already
# present in the environment.
: "${LOG_FILE:=/root/collect.log}"
export LOG_FILE
# Set the default log level to INFO if the
# environment variable isn't already set.
: "${DEFAULT_LOG_LEVEL:=INFO}"
export DEFAULT_LOG_LEVEL
# Log a message to a file and to standared error.
#
# NB: You may want to change the possible values
# for log levels (a.k.a. severity) based on your
# target logging system. For example, syslog
# also accepts `CRIT`, `ALERT`, and `EMERG`.
log_message () {
local date filename log_level log_msg
filename=$(basename "${BASH_SOURCE[0]}" ".sh")
date=$(date --rfc-3339=seconds | tr -d '\r\n')
log_level="${1:-$DEFAULT_LOG_LEVEL}"
log_level="${log_level^^}"
# Remove the first positional parameter if it's a
# defined log severity level.
[[ "${1@U}" =~ DEBUG|INFO|WARN|ERROR|FATAL ]] && shift
log_msg="[${date}] $log_level -- ${filename}: $*"
echo "$log_msg" >> "$LOG_FILE"
echo "$log_msg" > /dev/stderr
}
참고: 위의 리팩토링 스크립트는 Bashism을 명확하게 사용하지만 어떠한 Bashism도 보고하지 않습니다. 그러나 shellcheck를 통해 깨끗하게 실행됩니다. 이식성이 편리함보다 우선한다면 Bash 확장이나 기타 쉘 관련 기능 대신 표준 *nix 유틸리티를 사용하도록 다시 작성할 수 있지만 쉘 이식성은 원래 질문과 이 답변의 범위를 벗어납니다.
프로그램에서는 log_message
기본이 아닌 심각도 수준을 사용하거나 사용하지 않고 함수를 호출할 수 있습니다. 예를 들어, 코드가 있는 경우example_app.sh그런 다음 전화하십시오.
log_message WARN "This is just an example."
스크립트는 다음을 기록합니다.
[2022-04-20 11:10:01-04:00] WARN -- example_app: This is just an example.
둘 다로그 수집그리고 표준 오류.
당신은 또한 볼 수 있습니다
- 시스템 로그 심각도 수준
- 루비기록계카테고리, 형식 및 심각도 수준
- 배쉬의쉘 매개변수 확장
- GNU Coreutils
- 주택 검사웹사이트그리고소스 코드