ティープロセス置換サブシェルからグローバル変数をエクスポートする

ティープロセス置換サブシェルからグローバル変数をエクスポートする
command | tee >(var="$(command1)") >(var1="$(command2)")
echo "$var $var1"

また、moreutils peeを試しました。

command | pee 'var="$(command)"' 'var1="$(command2)"' 

また、エクスポートコマンドを試しました。 tee >(export var="$(command1)") >(var1="$(command2)")

質問1 私の必要性は、1つのコマンドの出力を使用し、それを複数のコマンドの入力として使用することです。

質問2

function() { Array=("$1"); }
function String

上記の作品

command | parallel -I %% function %%

上記で動作しない配列が設定されていない場合、回避策はありますか?助けてください。

コマンド出力:

1 word
2 word
3 word
4 word
1 string
2 string
3 string
4 string

2つの連想配列をどのように設定しますか? 1つは単語で、もう1つはパイプ出力の文字列に設定しますか?配列1[1]=ワード配列1[2]=ワード

配列2[1]=文字列配列2[2]=文字列

答え1

@theyが述べたように、プロセスの置き換えはサブシェルで実行されるため、その割り当てはデフォルトのシェルには表示されません。pee同様で、parallel少なくとも後者はエクスポートされた関数を使用できますが、まだコードを実行する別のシェルを起動します。

一時ファイルを使用することもできます結果回避策として、入力データが結果より長い場合は、この方法が役に立ちます。たとえば、

seq 10 | tee >(wc -l > lines) >(wc -c > chars) > /dev/null
lines=$(< lines)
chars=$(< chars)

または多分

tmp1=$(mktemp)
tmp2=$(mktemp)
seq 10 | tee >(wc -l > "$tmp1") >(wc -c > "$tmp2") > /dev/null
lines=$(< "$tmp1")
chars=$(< "$tmp2")
rm -f "$tmp1" "$tmp2"

答え2

表示されたコードの外部シェルに表示されるように変数値を設定したいとします。

示されているすべての例では、変数の割り当てとexport実行はサブシェル(またはサブプロセス)で行われます。サブシェルでは変数が設定され、通常どおりに使用できます。ただし、サブシェルが終了すると、シェル変数か環境変数(「エクスポートされたシェル変数」)に関係なく、変数は失われます。子シェルは親シェルの環境に影響を与えることはできません。

ここでは一時ファイルを使用できます。

some-command >tmpfile

var1=$(other-command1 <tmpfile)
var2=$(other-command2 <tmpfile)

rm -f tmpfile

またはsome-commandマイナーなケース(シェル組み込みユーティリティのみを使用し、最小限のリソースを使用し、多くの出力を生成しない):

var1=$( some-command | other-command1 )
var2=$( some-command | other-command2 )

改行で区切られたデータを配列に読み込む(必要に応じて)作業は、readarrayinを使用して行われますbash

readarray -t array < <( some-command )

some-commandただし、コマンドが多数の出力を生成する場合は、必要に応じて実行しないことがあります。この場合は、awkPythonや他の言語を使用してパイプラインのデータを処理することをお勧めします。

答え3

parsetあなたが探しているもの--pipe --tee

mkfifo myfifo
command > myfifo &
env_parset var,var1 --pipe --tee ::: command1 command2 < myfifo
echo "$var $var1"

例:

command() { seq 10000; }
command1() { wc -l; }
command2() { wc -c; }
mkfifo myfifo
command > myfifo &
env_parset var,var1 --pipe --tee ::: command1 command2 < myfifo
echo "$var $var1"

command1とをcommand2エクスポートする場合は、次のものを使用できますparset

export -f command1 command2
mkfifo myfifo
command > myfifo &
parset var,var1 --pipe --tee ::: command1 command2 < myfifo
echo "$var $var1"

command1command2オプションが異なる同じコマンドの場合:

command > myfifo &
parset var,var1 --pipe --tee wc {} ::: -c -l < myfifo
echo "$var $var1"

配列として出力したい場合:

command > myfifo &
parset arr --pipe --tee wc {} ::: -c -l < myfifo
echo "${arr[0]} ${arr[1]} ${arr[2]}"

連想配列で出力が必要な場合:

typeset -A myassoc
command > myfifo &
parset myassoc --pipe --tee wc {} ::: -c -l < myfifo
echo "${myassoc[-c]} ${myassoc[-l]}"

他の人が指摘したように、パイプを使用してデータを/|にパイプすることはできません。なぜなら、サブシェルで/が生成されるからです。これがFIFOトリックが必要な理由です。parsetparallelparsetparallel

シェルで許可している場合は、次のこともできます。

typeset -A myassoc
parset myassoc --pipe --tee wc {} ::: -c -l < <(command)
echo "${myassoc[-c]} ${myassoc[-l]}"

詳細については、次を参照してください。 https://www.gnu.org/software/parallel/parset.html

関連情報