Linux 셸: stderr 및 stdout을 하나의 파일과 개별 파일에 동시에 파이프합니다(티 사용?)

Linux 셸: stderr 및 stdout을 하나의 파일과 개별 파일에 동시에 파이프합니다(티 사용?)

stdout을 하나의 파일로 캡처하고 stderr을 다른 파일로 캡처하고 둘 다 세 번째 파일로 캡처하는 파이프 스트림을 형성하고 싶습니다(따라서 전체 터미널 출력도 하나의 파일에 있음)

어떻게 든 이렇게 :

process ----+-- <stdout> --- + --- stdlog.txt 
            |                |
            |                }---- <terminal> --- alllog.txt
            |                |
            \-- <stderr> --- +---- errlog.txt 

나는 tee를 사용해야 한다는 것을 알고 있지만 그것을 알아낼 수 없습니다. 해결책이 있나요? Bash/sh가 선호됩니다...

도움을 주셔서 감사합니다. 정말 감사드립니다 !!!

답변1

첫째: 제가 권장하는 것은 아닙니다. 단일 파일에 [INFO] 및 [ERROR]와 같은 타임스탬프와 라벨을 기록된 메시지 앞에 추가하거나 두 파일에 타임스탬프만 추가하는 것이 아마도 더 좋고 신뢰할 수 있는 아이디어일 것입니다. 장기적으로. grep이나 정렬을 사용하여 원하는 다른 파일을 빌드할 수 있습니다.

귀하의 문제에 대해 : 나는 그것을 할 필요가 없었지만 아마도 명명된 파이프를 사용해야 할 것입니다. 테스트되지 않은 bash 예:

# Log one output type
function logger() {
    unique_file="$1"
    common_file="$2"
    # Tee reads from the function's standard input, writes to unique_file, appends to common_file, then outputs what was written
    tee "$unique_file" | tee -a "$common_file"
}

# Call your code's main function to start processing
main > >(logger info_log_file common_log_file) 2> >(logger error_log_file common_log_file >&2)

를 사용하고 싶은 유혹을 느낄 수도 있습니다 exec >"$info_pipe" 2>"$error_pipe". 그렇지 않으면 로그 파일이 사용 가능한 모든 디스크 공간을 채우게 만드는 루프가 생성됩니다.

Bash가 암시적 명명된 파이프를 지원하지 않는 경우(지원해야 하지만 그렇지 않은 환경을 본 적이 있음) mkfifo를 호출하여 이를 명시적으로 사용하고 싶을 수도 있지만 이렇게 하려면 더 많은 배관이 필요합니다.

# Log one output type
function logger() {
    unique_file="$1"
    common_file="$2"
    # Tee reads from the function's standard input, writes to unique_file, appends to common_file, then outputs what was written
    tee "$unique_file" | tee -a "$common_file"
}

# Setup logging
function prepare() {
    tmp_pipe_dir="$(mktemp -d)"
    error_pipe="$(mkfifo "$tmp_pipe_dir/error")"
    info_pipe="$(mkfifo "$tmp_pipe_dir/info")"
}

function cleanup() {
    rm -rf "$tmp_pipe_dir"
}

prepare
# Start logging, note that logger won't stop on its own. Removing the pipe files should do the trick
logger info_log_file common_log_file <"$info_pipe" &
logger error_log_file common_log_file <"$error_pipe" >&2 &
# Call your code's main function to start processing
main >"$info_pipe" 2>"$error_pipe"
cleanup

관련 정보