> cat b.txt
function first
{
sleep 1
echo $(echo $$)
}
function second
{
openssl enc -aes-256-cbc -k "$(first)"
}
echo nyi | second | second | second
>
> time sh -x b.txt
+ echo nyi
+ second
+ second
+ second
++ first
++ sleep 1
++ first
++ sleep 1
++ first
++ sleep 1
+++ echo 32383
+++ echo 32383
++ echo 32383
++ echo 32383
+ openssl enc -aes-256-cbc -k 32383
+++ echo 32383
+ openssl enc -aes-256-cbc -k 32383
++ echo 32383
+ openssl enc -aes-256-cbc -k 32383
ɚ��2;��<�Vp��H�����F�q�AHO��Sܽd��d4��X��#}
real 0m1.026s
user 0m0.016s
sys 0m0.025s
>
質問: このスクリプトが少なくとも 3 秒間実行されないのはなぜですか?
最初の関数には「sleep 1」があり、2 番目の関数では 3 回呼び出される必要があります。
「実際の 0m1.026s」によると、スリープは 1 回だけ実行されるようです。または、並列 (??) の場合、どうすれば線形にできますか?
答え1
パイプラインの各部分はほぼ同時に開始されます。
の3つの呼び出しはsecond
すべて同時に開始されます。これにより発生する3つのサブシェルはfirst
展開を呼び出し"$(first)"
、3つのsleep 1
呼び出しは同時に発生します(トレース出力で確認できます)。する起こる)。
パイプラインをシリアル化するのは I/O だけです。つまり、パイプライン内の 1 つのプロセスが前のプロセスからの入力を待機するか、次のプロセスによって出力が読み取られるのを待機します。
パイプラインのビットを順番に開始、実行、終了するには、次のようにします。
echo nyi | second >out1
second <out1 >out2
second <out2
つまり、それらを個別に実行し、中間結果をファイルに保存します。