私のバッシュ技術はゼロに近いです。 Wi-Fiインターフェイスのデータ転送速度を監視するスクリプトを考えました。
#!/bin/bash
rx_old=0
tx_old=0
speed() {
read rx_bytes < /sys/class/net/wlp9s0f0/statistics/rx_bytes
read tx_bytes < /sys/class/net/wlp9s0f0/statistics/tx_bytes
drx=$(((rx_bytes - rx_old) / 1024))
dtx=$(((tx_bytes - tx_old) / 1024))
rx_old=$rx_bytes
tx_old=$tx_bytes
echo "$drx KB/s $dtx KB/s"
}
while true;
do
echo $(speed)
sleep 1
done
これはうまくいきません。 rx_old 変数と tx_old 変数が更新されていないようです。関数内でこれらの変数を変更することはできないと思います。誰でもこれに洞察力を与えることができますか?
答え1
問題はですecho $(speed)
。内部コマンドは、サブシェル、$(...)
つまりスクリプトを実行するシェルのサブプロセスで実行されます。子シェルは親シェルの変数を変更できません。
その結果、メインシェルのrx_old
合計はtx_old
実際には更新されません。同じ名前の変数はサブシェルで更新されますが、サブシェルが終了すると消えます。
$(...)
関数がすでにエコーしたテキストをエコーするのはすべてであるため、必要ありませんspeed
。speed
これはメインシェルで実行され、これらの変数を更新する「naked」に置き換えることができます。