here-docとを使用できます。効率的でPOSIXに適した一般的なコレクターモデルを入手します。
. 8<<-\IOHERE /proc/self/fd/8
command
…
fn() { declaration ; } <<WHATEVER
# though a nested heredoc might be finicky
# about stdin depending on shell
WHATEVER
cat -u ./stdout | ./works.as >> expect.ed
IOHERE
ヒアドックを開くと、シェルにIOHERE入力トークンで信号を送り、リミッタートークンのもう一方の端に到達するまで、指定したファイル記述子に入力をリダイレクトする必要があります。私は見回しましたが、上で示したようにヒアドキュメント演算子と組み合わせてリダイレクトfd番号を使用する例は多く見ていませんが、その使用法はPOSIXの基本的なシェルコマンドガイドラインで明確に指定されています。ほとんどの人はstdinを指して撮影するだけですが、この方法でソーススクリプトレットを使用すると、stdinがフリーになり、構成アプリがブロックされたI / Oパスについて文句を言うことがなくなります。
ヒアドキュメントの内容は、指定したファイル記述子にストリームされ、次にシェルコードとして解釈され、によって実行されます。組み込み。ただし、特定のパスを指定せずに。。/ proc / selfパスで問題が発生する場合は、/ dev / fd / nまたは/ proc / $$を試してください。これと同じ方法は、パイプでも機能します:
cat ./*.sh | . /dev/stdin
おそらく、少なくとも見た目ほど賢くないでしょう。もちろん、shでも同じことができますが、。の目的は現在のシェル環境で実行することです。これはおそらくあなたが望んでいることであり、シェルによっては、heredocよりもはるかに動作しやすいです標準の匿名パイプを使用します。
とにかく、おそらくお気づきかもしれませんが、私はまだあなたの質問に答えていません。しかし、考えてみると、heredocがすべてのコードを。'sにストリームするのと同じように、単一の単純なアウトポイントも提供します。
. 5<<EOIN /dev/fd/5 |\
tee -a ./log.file | cat -u >$(tty)
script
…
more script
EOIN
したがって、heredocで実行されたコードのすべての端末の標準出力は、からパイプアウトされます。もちろん、単一のパイプから簡単にティーオフできます。現在のstdoutの方向が不明なため、バッファなしのcat呼び出しを含めましたが、おそらく冗長で(ほぼ間違いなく書かれているとおりです)、パイプラインはおそらくティーで終了する可能性があります。
また、2番目の例で欠落しているバックスラッシュの引用を疑問視するかもしれません。この部分は、ジャンプインする前に理解することが重要であり、どのように使用できるかについていくつかのアイデアを提供するかもしれません。引用されたheredocリミッター(これまでIOHEREとEOINを使用し、最初にバックスラッシュで引用しましたが、「シングル」または「ダブル」引用は同じ目的に役立ちます)は、シェルでのパラメーター展開の実行を禁止しますただし、引用符で囲まれていないリミッターは、そのコンテンツを展開したままにします。あなたのヒアドキュメントがそうであるときのこれの結果。ソースは劇的です:
. 3<<HD ${fdpath}/3
: \${vars=$(printf '${var%s=$((%s*2))},' `seq 1 100`)}
HD
echo $vars
> 4,8,12…
echo $var1 $var51
> 4 104
ヒアドキュメントリミッターを引用しなかったため、シェルは内容の読み取りを行い、結果のファイル記述子をに提供する前に内容を展開しました。実行する。これは本質的に、コマンドが2回解析されることになりました-とにかく拡張可能なコマンドです。バックスラッシュで$ varsパラメーター展開を引用したため、シェルは最初のパスでの宣言を無視し、バックスラッシュのみを削除したため、printf展開されたコンテンツ全体がnullの場合に評価できるようになりました。2番目のパスでスクリプトを入手しました。
この機能は、evalを使用するよりもheredocで引用する方がはるかに簡単であり、同様に危険である場合でも、組み込みの危険なevalシェルが提供できるものと基本的にまったく同じです。注意深く計画しない限り、習慣として「EOF」リミッターを引用するのがおそらく最善です。ただ言って。
編集:ええ、私はこれを振り返って、それは少し長すぎると思います。行う必要があるのが複数の出力を1つのパイプに連結することだけである場合、最も簡単な方法は以下を使用することです。
{ or ( command ) list ; } | tee -a ea.sy >>pea.sy
カーリーは現在のシェルでコンテンツを実行しようとしますが、括弧は自動的にサブアウトします。それでも、誰でもあなたにそれを伝えることができ、少なくとも私の意見では、。特にシェルが実際にどのように機能するかを理解したい場合、heredocソリューションははるかに貴重な情報です。
楽しんで!