必要に応じて、関数内の関数は何度も呼び出されませんか?

必要に応じて、関数内の関数は何度も呼び出されませんか?
> 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秒間実行されるのはなぜですか?

最初の関数には「スリープ1」があり、2番目の関数ではこの関数を3回呼び出す必要があります。

「実際の0m1.026s」によると、睡眠は一度だけ実行されるようです。それとも平行(??)なら、どのように線形にすることができますか?

ベストアンサー1

パイプラインのさまざまな部分が同時に(ほぼ)開始されます。

3 つの通話がすべてsecond同時に開始されます。これが生成する3つのサブシェルはfirst拡張を呼び出し"$(first)"、これら3つのsleep 1呼び出しは同時に発生します(トレース出力で見ることができます)。する発生する)。

I/O 直列化されたパイプのみがあります。つまり、パイプ内の1つのプロセスは、前のプロセスの入力を待つか、次のプロセスが出力を読み取るのを待ちます。

パイプラインのさまざまな部分を順番に開始、実行、および終了するには、次の手順を実行します。

echo nyi | second >out1
second <out1 >out2
second <out2

つまり、別々に実行し、中間結果をファイルに保存します。

おすすめ記事