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

...次のように、他の2つのファイル名を使用して再実行します。

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

関連情報