기능 매개변수로 펌프 명령 출력

기능 매개변수로 펌프 명령 출력

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

# 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

출력을 처리하기 위해 쉘 루프를 사용하는 것은 좋은 생각이 아니지만 적어도 속도가 느립니다. 바라보다:쉘 루프를 사용하여 텍스트를 처리하는 것이 왜 나쁜 습관으로 간주됩니까?. 파일을 리디렉션하거나 로 리디렉션하려는 경우에는 SetupRedirect를 /dev/null사용하세요 exec.

관련 정보