bash 내장 기능만 사용하여 unbuffer/script/tee를 사용하지 않고 파일 설명자 stdout 및 stderr의 실제 복사본을 만드는 방법은 무엇입니까?

bash 내장 기능만 사용하여 unbuffer/script/tee를 사용하지 않고 파일 설명자 stdout 및 stderr의 실제 복사본을 만드는 방법은 무엇입니까?

내 목표는 stdout응용 프로그램( ) 및 의 일반적인 동작을 유지하면서 응용 프로그램( )의 모든 출력을 파일로 복사, 리디렉션 및 리디렉션하는 것입니다.stderrapt-getapt-getstdoutstderr

stdout파일 설명자 sum 의 실제 복사본을 만드는 방법은 무엇입니까 stderr? 나는 가능한 stdout한 "자연스러운" 상태를 유지하고 싶습니다 . stderr예를 들어 실행 중인 경우 apt-get색상 및 진행률 정보를 유지하고 싶습니다. [1]

여기에 예가 있습니다. (래퍼는 더 많은 일을 하며 단순하게 유지합니다.)

#!/bin/bash

temp_dir="$(mktemp --directory)"
logfile="$temp_dir/log"

unbuffer apt-get "$@" 1> >(tee -a "$logfile") 2> >(tee -a "$logfile" >&2)

unbuffer// 내장 함수를 사용 하지 script않고 이를 달성하는 것이 가능합니까 ?teebash

(래퍼를 더 간단하게 만들고 외부 바이너리에 대한 의존성을 줄이기 위해. 그렇지 않으면 필수 액세스 제어 등과 충돌이 발생할 수 있습니다.)

(사용스크립트(1)매뉴얼 페이지에서는 비대화형 스크립트에서의 사용을 권장하지 않습니다. )


[1]

22% [8 Packages 3,449 kB/7,098 kB 49%]
174 kB/s 4min 57s

답변1

이것POSIX쉘 가짜 tee함수에는 종속성이 없습니다.

faketee() {
   if [ "$1" = '-a' ] ; then 
      shift
      while read -r x ; do 
         echo "$x" >> "$1"
         echo "$x"
      done
   else  
      while read -r x ; do 
         echo "$x" > "$1"
         echo "$x"
      done
   fi
}

bash기존 파일에서 테스트합니다 ls(다음 줄로 출력).표준 출력) 및 존재하지 않는 파일 이름(다른 줄을표준 오류 오류율):

cd /tmp
ls /bin/bash /bin/nosuchfile  1>  >(faketee -a std.log) \
                              2>  >(faketee -a err.log >&2)

산출:

/bin/bash
ls: cannot access '/bin/nosuchfile': No such file or directory

...다음과 같이 다른 두 개의 파일 이름을 사용하여 다시 실행합니다.

ls /bin/dash /bin/nohowsuchfile  1>  >(faketee -a std.log) \
                                 2>  >(faketee -a err.log >&2)

산출:

/bin/dash
ls: cannot access '/bin/nohowsuchfile': No such file or directory

이제 로그 파일을 확인하여-a미정스위치 작동 원리:

grep -n '.' std.log err.log

출력에는 연결된 리디렉션이 있어야 하는 위치가 표시됩니다.

std.log:1:/bin/bash
std.log:2:/bin/dash
err.log:1:ls: cannot access '/bin/nosuchfile': No such file or directory
err.log:2:ls: cannot access '/bin/nohowsuchfile': No such file or directory

관련 정보