함수 인수로 펌프 명령 출력

함수 인수로 펌프 명령 출력

내 스크립트에는 다음과 같은 매우 간단한 기능이 있습니다.

# Used for debug tracing.
log()
{
    :
    echo "log: $1"
}

한 곳에서 로깅을 사용자 정의/해제할 수 있다는 아이디어입니다. 매우 조잡합니다.

이제 릴리스 구성 시 스크립트가 전혀 출력을 생성하지 않기를 원합니다. 내가 생각한 유일한 솔루션이지만 매우 건조하지 않습니다.

TMPFILE='/tmp/tempfilewithpossiblyuniquename'
cmd 1>"$TMPFILE" 2>"$TMPFILE"
cat "$TMPFILE" | xargs log
rm "$TMPFILE"

~을 위한모든 명령 하나하나. 이를 개선하는 방법은 무엇입니까?


편집: 수집하고 싶습니다모두로 출력 stdout하고 stderr를 통해 채널을 보냅니다 log(). 그런 다음 log()모든 것을 무시하고, 파일에 기록하고, 인쇄하는 등을 선택할 수 있습니다.

답변1

첫째, 해당 함수는 전송된 모든 항목의 첫 번째 "단어"만 기록 합니다 $1."$*"

둘째, 이런 종류의 작업을 수행하는 방법은 (보통 POSIX의 경우처럼) 무수히 많습니다. 나는 아마도 다음과 같이 갈 것입니다 :

log() {
    cat - >> "$logfile"
}

do_stuff | log

하지만 다음과 같이 할 수도 있습니다.

(
    do_stuff
    do_more_stuff
) >> "$logfile"

./thing 1> /dev/null 2> &1모든 출력을 완전히 억제하는 것은 일반적으로 "코드 내에서" 잠그는 것보다 호출 환경(예: )에 남겨두는 것이 가장 좋습니다 . 그것은 말했다:

squashout="true"  # comment this out to stop killing output
if ! [[ "true" = "${squashout-false}" ]]; then 
  # Redirect stdout and stderr to the null device.  
  exec 1> /dev/null
  exec 2> /dev/null
fi

답변2

절대 간단한 출력은 없습니다. 스크립트를 stdout다음 stderr으로 리디렉션하면 됩니다 /dev/null.

exec >/dev/null 2>&1

이는 셸 자체와 이후에 실행되는 모든 명령에 영향을 미칩니다. 출력이 리디렉션되는 위치를 선택하려면 조건부로 실행하세요.

if [ "$output_to_file" = 1 ]; then
    exec > "$outputfilename" 2>&1
elif [ "$output_suppress" = 1 ]; then
    exec > /dev/null 2>&1
fi

참고로 억제하는 것은모두출력은 아마도 좋은 생각이 아닐 것입니다. 사용자가 원할 가능성이 매우 높습니다.일부오류에 대한 알림.


함수를 통해 출력을 전달하고 Bash/ksh/Zsh를 실행하는 경우 프로세스 대체를 사용할 수 있습니다.

#!/bin/bash
mangle_output() {
    # do something smarter here
    while read -r line; do
        echo "output: $line";
    done;
}
# redirect stdout and stderr to the function
exec > >(mangle_output) 2>&1
echo something that produces output

쉘 루프를 사용하여 출력을 처리하는 것은 그다지 좋은 생각은 아니지만 적어도 속도는 느립니다. 보다:쉘 루프를 사용하여 텍스트를 처리하는 것이 나쁜 습관으로 간주되는 이유는 무엇입니까?. 원하는 것이 파일을 리디렉션하는 것뿐이라면 리디렉션을 설정하는 데 /dev/null사용하세요 .exec

관련 정보