どうを送りたいので、標準出力に出力の一工程で複数のプロセスを用いた好ましくは名前のない管Unix(Windows)?

StackOverflow https://stackoverflow.com/questions/60942

質問

私はリダイレクトの標準出力に出力プロセスproc1二つのプロセスproc2とproc3:

         proc2 -> stdout
       /
 proc1
       \ 
         proc3 -> stdout

てみました

 proc1 | (proc2 & proc3)

が見られるとは思えませんの作業、すなわち

 echo 123 | (tr 1 a & tr 1 b)

書き込みます

 b23

標準出力に出力ではなく

 a23
 b23
役に立ちましたか?

解決

編集部注:
- >(…)代替工程 である 標準外のシェルの特徴一部の POSIX互換の貝殻: bash, ksh, zsh.
-この答えを誤って送信出力処置換の出力のパイプライン すぎ: echo 123 | tee >(tr 1 a) | tr 1 b.
-出力は、工程現場からの置換するunpredictablyインターリーブ、合を除き、 zsh, のパイプラインの終了することができます前にコマンド内 >(…) います。

Unix(またはmacを使用 tee コマンド:

$ echo 123 | tee >(tr 1 a) >(tr 1 b) >/dev/null
b23
a23

通常ことはできませ tee へのリダイレクト出力を複数のファイルが利用>(...)まで リダイレクトを別の工程です。なので、一般的に、

$ proc1 | tee >(proc2) ... >(procN-1) >(procN) >/dev/null

いと考えている。

Windowsは思えないのシェルには等価です。Microsoftの Windows PowerShelltee コマンドになってる。

他のヒント

のようにdF、 bash での利用 >(…) 構築の実行コマンドのファイル名を指定します。(あるもの <(…) の構築を代行する 出力 他のコマンドのファイル名が、それは無関係で、今はもう完全性).

いbashや走行システムの古いバージョンのbashできな手で何bashは、FIFOのファイルです。

の一般的な方法で実現したいものは:

  • 設定を変更するプロセスを受けるべきであり、出力のコマンドは、多くのFifo、好ましくは、グローバルフォルダ:
    subprocesses="a b c d"
    mypid=$$
    for i in $subprocesses # this way we are compatible with all sh-derived shells  
    do
        mkfifo /tmp/pipe.$mypid.$i
    done
  • 開始すべてのサブプロセスを待ってから入力したFifo:
    for i in $subprocesses
    do
        tr 1 $i </tmp/pipe.$mypid.$i & # background!
    done
  • 実行を行うコマンドteeingのFifo:
    proc1 | tee $(for i in $subprocesses; do echo /tmp/pipe.$mypid.$i; done)
  • 最後に、削除のFifo:
    for i in $subprocesses; do rm /tmp/pipe.$mypid.$i; done

注意:互換性の理由で入っていて、 $(…) とbackquotesが、それが出来なかったこの答えにbackquote使用します。通常、 $(…) れるのは仕事でも、古いバージョンのkshがっていることを確認してくださいませた上で封の 部backquotes.

Unix(bash, ksh, zsh)

dFの回答 を含む 種子 の回答に基づく tee出力 処置換
(>(...)ません 作業によっては、お客様の要件:

注そのプロセスの置換をして 標準外の 機能を中心) POSIXには-特徴-み殻などの dash (ある行為として /bin/sh Ubuntu, のためのインスタンス)、 ない ます。シェルスクリプトを対象に /bin/sh すべ ない に依存します。

echo 123 | tee >(tr 1 a) >(tr 1 b) >/dev/null

落とし穴 このアプローチ:

  • 予測できないので、非同期出力動作:の出力ストリームからのコマンドの出力処理が置換 >(...) interleaveが予想する。

  • bashkshzsh が参照例外):

    • 出力の場合は到着 のコマンドは終了いたしました。
    • その後のコマンドが実行 コマンドは、その置換が完了して - bashkshない の出力処理が置換-普プロセスに仕上がりは、少なくともデフォルトです。
    • jmb でもコメントdFの回答:

このコマンドを始めた内部 >(...) 酵元のシェルで、簡単かを判定するのに合わない場合はご相談ください;の tee 仕上がりになり書きを全てのものに置換されたプロセスが消費のデータから様々なバッファーをカーネルおよびファイルI/O、何時間は内部データの取り扱い.できるとの出会いは競合状態が外殻を頼りになされたサブプロセス。

  • zsh は、このときシェル デフォルトのプロセスの出力処理の置換に仕上がり, を除く であれば stderr このリダイレクトされ一2> >(...)).

  • ksh (少なくともバージョン 93u+)は使用できるの引数は以下の wait 待つの出力処理が置換-普プロセスに仕上がります。
    るということに注意してくださるインタラクティブセッションを待たず申請中 背景に雇用 もしています。

  • bash v4.4+ できるのを待つ 最近では 開始出力処理で代用すること wait $!, ものの、引数以下の waitない ですが、このに適しないコマンド 複数の 出力処理が置換.

  • しかし、 bashksh強制 による配管のコマンド | cat, なお、このコマンドを実行される 独立したサブシェルで. 注意:

    • kshksh 93u+)をサポートしていない送信 stderr 出力処置換(2> >(...));このような試みが 無視され.

    • ながら zsh (commendably)同期 デフォルト のり) 標準出力に出力 出力処理が置換もの | cat 技術はできなく同期と stderr 出力処理ャ2> >(...)).

  • しかし、 場合でもすることを保証するため 同期実行, の問題 unpredictablyインターリーブ出力 が残っています。

以下のコマンドが実行 bash または ksh, この問題行動(すでに数回見る 症状):の AFTER は通常の印刷 出力から出力置換の出力から、後者はインターリーブunpredictably.

printf 'line %s\n' {1..30} | tee >(cat -n) >(cat -n) >/dev/null; echo AFTER

:

  • 保証の特定の単コマンドの出力配列:

    • bashkshzsh 支援す。
  • 同期の実行:

    • 可もしくは stderr-仕入出力処理が置換:
      • zsh, り出されるとのことであっ 非同期。
      • ksh, い 働いていない全.

まとともに暮らしながらこれらの制限は、出力処理の置換を実行可能なオプション(例えば、すべての書分離出力ファイル).


ご注意 tzotのも面倒なものの、潜在的にPOSIXに準拠した溶液 も展示予想外の出力動作;しかし、よ wait することを保証できるその後のコマンドを起動しない実行までのすべての背景-プロセスは終了いたしました。
参照下 のための より強固な同期,直列化された出力を実施.


のみ 簡単な bashと予測可能な出力動作 にし、 非常に遅く大きな入力設定, ので、シェルのループは、本質的に遅くなります。
また、この 交互 出力ラインからの対象コマンド.

while IFS= read -r line; do 
  tr 1 a <<<"$line"
  tr 1 b <<<"$line"
done < <(echo '123')

Unixを使用GNU並列)

の設置 GNU parallel が可能 強固なソリューション直列化された(単コマンド)の出力 るまで ルチコアcpuを生かして並列実行:

$ echo '123' | parallel --pipe --tee {} ::: 'tr 1 a' 'tr 1 b'
a23
b23

parallel デフォルトで確実に出力からコマンドなinterleave(この動作を変更できる見 man parallel).

注意:一部のLinux distros付 異なる parallel 明るいはコマンドにより、以下の使用 parallel --version るかを決定した場合です。


Windows

ジェイBazuziのも答え 表示方法を示しな PowerShell.とはいえ:彼の答えは、アナログのループを bash 答えでき 非常に遅く大きな入力設定 とも 交互 出力ラインからの対象コマンド.



bashに基づくものの、その他の携帯Unix液同期実行、出力の直列化

以下は、シンプルですが合理的に実施アプローチを発表 tzotの回答 たまた提供:

  • 同期実行
  • 直列化され(グループ化)の出力

ないものを厳重にPOSIX準拠したものであり、 bash スクリプトで行うべき 携帯載のUnixプラットフォーム bash.

注意:べき本格的な実施を発売、MITライセンスの下で この概要.

保存されると以下のコードとしてスクリプト fanout, で実行可能なけintご PATH, 、コマンドからの疑問に思うとしており

$ echo 123 | fanout 'tr 1 a' 'tr 1 b'
# tr 1 a
a23
# tr 1 b
b23

fanout スクリプトのソースコード:

#!/usr/bin/env bash

# The commands to pipe to, passed as a single string each.
aCmds=( "$@" )

# Create a temp. directory to hold all FIFOs and captured output.
tmpDir="${TMPDIR:-/tmp}/$kTHIS_NAME-$$-$(date +%s)-$RANDOM"
mkdir "$tmpDir" || exit
# Set up a trap that automatically removes the temp dir. when this script
# exits.
trap 'rm -rf "$tmpDir"' EXIT 

# Determine the number padding for the sequential FIFO / output-capture names, 
# so that *alphabetic* sorting, as done by *globbing* is equivalent to
# *numerical* sorting.
maxNdx=$(( $# - 1 ))
fmtString="%0${#maxNdx}d"

# Create the FIFO and output-capture filename arrays
aFifos=() aOutFiles=()
for (( i = 0; i <= maxNdx; ++i )); do
  printf -v suffix "$fmtString" $i
  aFifos[i]="$tmpDir/fifo-$suffix"
  aOutFiles[i]="$tmpDir/out-$suffix"
done

# Create the FIFOs.
mkfifo "${aFifos[@]}" || exit

# Start all commands in the background, each reading from a dedicated FIFO.
for (( i = 0; i <= maxNdx; ++i )); do
  fifo=${aFifos[i]}
  outFile=${aOutFiles[i]}
  cmd=${aCmds[i]}
  printf '# %s\n' "$cmd" > "$outFile"
  eval "$cmd" < "$fifo" >> "$outFile" &
done

# Now tee stdin to all FIFOs.
tee "${aFifos[@]}" >/dev/null || exit

# Wait for all background processes to finish.
wait

# Print all captured stdout output, grouped by target command, in sequences.
cat "${aOutFiles[@]}"

年@dF:うユーティは思ったので思表示をすることでユー.

PS > "123" | % { 
    $_.Replace( "1", "a"), 
    $_.Replace( "2", "b" ) 
}

a23
1b3

注各オブジェクトの最初のコマンドを処理し、次のオブジェクトが作成されます。これをスケーリングには大型用の入力端子が付いています。

別の言い方ないです

 eval `echo '&& echo 123 |'{'tr 1 a','tr 1 b'} | sed -n 's/^&&//gp'`

出力:

a23
b23

作成不要独立したサブシェルでこちら

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top