해결됨:
몇 달 전, 나는 로그인 쉘 스크립트에 관심을 갖게 되었습니다.
첫 번째 아이디어는 다음과 같이 함수를 수동으로 기록하는 것입니다.
add2log() {
printf "$(date)\tINFO\t%s\t%s\n" "$1" "$2" >>"$logPATH"
}
하지만 자동화하고 싶습니다. 예를 들어 STDERR이 자동으로 기록됩니다.
오랜만에 만족스러운 답을 찾았고, 드디어 공유하는 시간을 갖게 되었습니다.
이제 각 셸 스크립트에 대해 "main.sh"를 사용하여 로깅 기능과 구성(로그 및 구성 파일 설정)을 보관합니다. 다음과 같습니다.
#!/bin/bash
###################################################################
# MY HEADERS
###################################################################
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#~~~~~~~~~~~~~~~~~~Global vars
mainScriptNAME=$(basename "$0")
mainScriptNAME="${mainScriptNAME%.*}"
mainScriptDIR=$(dirname "$0")
version="v0.0"
scriptsDIR="$mainScriptDIR/SCRIPTS"
addonsDIR="$mainScriptDIR/ADDONS"
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#~~~~~~~~~~~~~~~~~~LOGGER FUNCS
manualLogger() {
# $1=PRIORITY $2=FUNCNAME $3=message
printf "$(date)\t%s\t%s()\t%s\n" "$1" "$2" "$3" >>"$logFilePATH"
}
stdoutLogger() {
# $1=message
printf "$(date)\tSTDOUT\t%s\n" "$1" >>"$logFilePATH"
}
stderrLogger() {
# $1=message
printf "$(date)\tSTDERR\t%s\n" "$1" >>"$logFilePATH"
}
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#~~~~~~~~~~~~~~~~~~LOG & CONF
createLog() {
# code to set and touch logFilePATH & confFilePATH
manualLogger "INFO" "${FUNCNAME[0]}" "Log file created."
}
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#~~~~~~~~~~~~~~~~~~MAIN
#
createLog
#run scripts
{
#
source "$scriptsDIR/file1.sh"
doSomthing1
doSomthing2
#
source "$scriptsDIR/file2.sh"
anotherFunction1
anotherFunction2
...
} 2> >(while read -r line; do stderrLogger "$line"; done) \
1> >(while read -r line; do stdoutLogger "$line"; done)
다시 말해서:
- 내가 실행하려는 모든 스크립트/함수는 ./SCRIPTS 폴더의 별도 파일에 있습니다(그래서 내 main.sh는 거의 항상 동일합니다).
- STDOUT 및 STDERR을 캡처하기 위해 이 모든 스크립트를 { ... } 그룹에 넣습니다.
- 해당 STDOUT 및 STDERR은 해당 로거 기능으로 리디렉션됩니다.
로그 파일은 다음과 같습니다(수동 로거, STDOUT 로거 및 STDERR 로거의 예).
Lun 23 mai 2022 12:20:42 CEST INFO createLog() Log file created.
Lun 23 mai 2022 12:20:42 CEST STDOUT Some standard output
Lun 23 mai 2022 12:20:42 CEST STDERR ls: sadsdasd: No such file or directory
팀은 모든 출력을 로그로 수집합니다. 대신 리디렉션 2> >(while read ...
과 . 1> >(while read ...
예를 들어 doSomthing1
STDOUT 및 STDERR은 기록되지만 doSomthing2
STDERR만 리디렉션됩니다.
답변1
표면적으로는 방금 디버깅 문을 추가한 것처럼 보입니다. 여기서 "무거운"이란 무엇을 의미합니까? Bash 스크립팅(또는 해당 문제에 대한 다른 프로그래밍 언어)에서 무언가를 다시 에코해야 하는 경우 인터프리터에게 echo
전달한 내용을 알려주는 명령문이 있어야 합니다 .
스크립트(또는 코드 조각)의 특정 지점에서 작업을 수행하려는 경우 명령을 작성하는 것을 대체할 수 있는 방법은 없습니다.
IO 리디렉션을 사용하여 다양한 트릭을 얻을 수 있지만 원하는 효과를 얻으려면 시작 부분과 끝 부분에 하나씩 두 개의 명령문이 있어야 합니다.
완전히 문서화된 스크립트를 원한다면 을 참조하십시오 set -x
. 스크립트의 특정 기능만 기록하려면 set -x
suhshell에서 해당 기능을 사용하세요.
(set -x; func1)
답변2
전용 디렉터리에 플래그 파일을 사용합니다.
foo.bash:
#!/bin/bash
[[ -f $HOME/.local/debug/foo.debug ]] && \
source $HOME/.local/debug/foo.debug
...
foo.debug
와 같은 것을 포함하여 내가 좋아하는 모든 것을 파일에 넣을 수 있으며 debug_foofunction=1
나중에 디버그 코드를 호출(또는 호출하지 않음)하는 데 사용할 수 있습니다 foo
( 주의하세요. 정의되지 않을 수 있음). 간단히 말하면 모든 디버깅 코드가 꺼집니다. 으로 변경하면 다른 디버깅 설정(예: )을 유지하면서 디버깅을 끌 수 있습니다 .foofunction
debug_foofunction
rm $HOME/.local/debug/foo.debug
debug_foofunction=0
foofunction
debug_foootherfunction=1
man bash
" trap
" 내장 에 대해 읽어보세요 .
실제 해결책은 복잡한 스크립트를 작성하지 않는 것입니다. 문제 세트에 맞는 프로그래밍 언어를 사용하십시오.
항상 스크립트를 https://shellcheck.net
구문 검사기 에 붙여넣거나 shellcheck
로컬로 설치하십시오. 사용을 shellcheck
개발 프로세스의 일부로 만드세요 .