시간 및 상태와 함께 메시지를 기록하는 기능이 있는 Bash 스크립트가 있는데 스크립트의 80개 열만 유지하려고 합니다.
#!/bin/bash
log_message() {
echo "[$(date)]-[$1] : $2" >> log.txt
}
varName="John Doe"
# line break to not exceed 80 columns
log_message "WARNING" "I am "${varName}" and i want to limit this line \
to 80 columns"
로그 파일의 결과가 예상과 다릅니다.
[Fri Jun 24 13:50:12 CEST 2022]-[WARNING] : I am John
Bash에서 이를 수행하는 올바른 방법은 무엇입니까?
답변1
귀하의 경우 문제는 줄 연속에 있는 것이 아니라 두 번째 매개변수에 큰따옴표를 이스케이프 처리하지 않고 사용하고 있다는 사실에 있습니다(@Stéphane의 답변을 보면 실제로 이 작업을 의도했을 수도 있습니다. 이것이 좋은 생각이 아닌 이유는 아래를 참조하세요.). 시도 해봐
log_message "WARNING" "I am \"${varName}\" and i want to limit this line \
to 80 columns"
이전에 이스케이프되지 않은 따옴표를 사용하여 ${varName}
변수 참조는 이제 실제로외부큰따옴표 및 분사이므로 log_message
호출에는 다음 매개변수가 표시됩니다.
WARNING
I am John
(해당John
부분은 "닫는" 큰따옴표 바로 뒤에 오기 때문에 여전히 두 번째 태그의 일부로 간주됩니다.)Doe and i want to limit this line to 80 columns
(Doe
두 번째 매개변수와 같은 이유로 세 번째 매개변수에 추가됨)John
그러나 함수는 log_message
처음 두 인수만 해석하므로 나머지 문자열 조각은 손실됩니다.
답변2
참고로 더 잘 쓸 수 있습니다 log_message
.bash
exec {logfd}>> log.txt
log_message() {
local severity="$1" message
shift
for message do
printf '[%(%FT%T%z)T]-[%s] : %s\n' -1 "$severity" "$message" >&"$logfd"
done
}
이렇게 하면 date
매번 명령을 실행하고 로그 파일을 다시 열 필요가 없으며 여러 메시지를 전달할 수 있습니다(각 메시지는 별도의 줄에 표시됨).
그런 다음 @AdminBee가 이미 언급한 대로 줄 연속에 사용됩니다 \
. sh/bash에서는 대부분의 다른 언어와 달리 인수 확장이나 따옴표를 제외하고 쉘에 특수한 문자를 중심으로 회전합니다. 결국 해당 부분을 인용되지 않은 채로 남겨 두게 "...."${var}"..."
됩니다 ${var}
. 즉, 분할+글로브를 거친다는 뜻입니다!
log_message WARNIN\
G "I am ${varName}\
and I want to lim\
it this line to 20\
columns"
선택이다. 이러한 줄 연속(다음에 \
개행 문자가 옴)은 큰 따옴표 안이나 바깥쪽 또는 here 문서에서 사용할 수 있지만 작은 따옴표 안이나 따옴표 구분 기호가 있는 here 문서에서는 사용할 수 없습니다.
이를 통해 log_message
다음도 수행할 수 있습니다.
log_message WARNING \
"I am ${varName}" \
'and I want to limit' \
'the length of the lines' \
'in the log file.'
입력하다 log.txt
:
[2022-06-24T13:28:46+0100]-[WARNING] : I am John Doe
[2022-06-24T13:28:46+0100]-[WARNING] : and I want to limit
[2022-06-24T13:28:46+0100]-[WARNING] : the length of the lines
[2022-06-24T13:28:46+0100]-[WARNING] : in the log file.