シェル変数を印刷すると、空の出力が生成されます。

シェル変数を印刷すると、空の出力が生成されます。

次のプログラムがあり、$varプログラムの実行時間で埋められた変数を印刷したいと思います。echoただし、コンソールに出力するときはprintf値が空です。

プログラム:

#!/bin/bash
for n in 1 2 3 4;
    do my_time="$(time var=$(echo "scale=100; 4*a(1)" | bc -l))";
    
    echo $var
    echo $my_time       
    printf "Value of PI is :%s\n" $var
done

出力:

real    0m0.003s
user    0m0.000s
sys 0m0.000s


Value of PI is :

real    0m0.004s
user    0m0.000s
sys 0m0.000s


Value of PI is :

real    0m0.004s
user    0m0.000s
sys 0m0.000s


Value of PI is :

real    0m0.004s
user    0m0.000s
sys 0m0.000s


Value of PI is :

問題は何であり、どのように解決しますか?

答え1

コマンド置換は$(...)サブシェルでコマンドを実行します。子シェルで変数を設定すると、親シェルに伝播されません。

この場合、time組み込み関数が標準出力やエラーとして出力しないため、問題がさらに大きくなります。出力をキャプチャするには、サブシェルで実行し、そのシェルのstderrをキャプチャする必要があります。しかし、その後、変数を設定することはできません。

私が見ることができる唯一の方法は、コマンドを2回実行することです。一度は出力をキャプチャし、一度は時間をキャプチャすることです。

    var=$(bc -l <<< 'scale=100; 4*a(1)')
    my_time=$( (time bc -l <<< 'scale=100; 4*a(1)') 2>&1 >/dev/null)

または、両方の詳細を同時にキャプチャし、後で分離します。

    out=$( (time bc -l <<< 'scale=100; 4*a(1)') 2>&1)
    var=${out%real*}
    my_time=real${out#*real}

関連情報