こんにちは皆さん、現在whileループにzenityプログレスバーを実装しようとしていますが、増分されるはずの変数が増分されないことに気付きました。これが私が試したサンプルのテストスクリプトです。
i=0
p=0
while [ $i -lt 10 ]
do
i=$[$i + 1]
echo $i
p=$[$p + 1]
done | (zenity --progress --title="test" --text="test")
echo "i: $i p: $p"
プログレスバーが機能していることに気付きましたが、カウンターとして使用される変数p
は、Zenityの影響を受けました。私のコードに何か問題がありますか?変数i
はプログレスバーを移動するために値をエコーするためのもので、変数p
は他の目的のためのものです。 p
とi
の値は、whileループ内でインクリメントしても、両方とも0
です。
Zenityプログレスバーを削除せずに変数p
とi
をインクリメントする方法があることを望んでいます。しかし、(zenity --progress --title="test" --text="test")
行が削除された後に変数の増分が機能する理由はわかりません。
追加
進行状況バーが終了した後に変数i
およびp
を使用する方法は?もう1つの質問は、whileループを()
で囲む必要がありますか?
助けてくれてありがとう!
インクリメントとすべてがまったく問題ないようです。ただし、すべての増分は、zenity
に渡されるサブシェル内で行われます。これが、サブシェルの外部でecho
変更を取得しても変更を取得できない理由です。私はあなたのスクリプトを使用していますが、変数を印刷するものを追加するだけでdo while
zenity
ポップアップウィンドウでループします。 Zenity Progressダイアログの構文の詳細については、 gnomeヘルプページ を参照してください。以下のスクリプトを実行して結果を確認します。
#!/bin/bash
i=0
p=0
(while [ $i -lt 100 ]
do
i=$[$i + 10]
echo $i ; sleep 1
echo "# now i is $i and p=$p"
p=$[$p + 1]
done) | zenity --progress --title="test" --text="test"
echo "i: $i p: $p"
i
の増分を10に変更し、i
を使用してプログレスバーの増分を作成し、sleep 1
進行を知覚できるようにします。
Observation:値はzenity
ポップアップで増加することが示されていますが。端末上で変更されていないことを示しています、i: 0 p: 0
これが役立つことを願っています。
サブシェル変数を外部で使用する方法
親シェルは、サブシェルの変数を使用できません。 サブシェルの詳細はこちら を見つけることができます。しかし、サブシェルから一時ファイルに変数を書き込み、その親が読み取ることができます。最高の方法ではないかもしれませんが、機能します。
#!/bin/bash
..
(while [ $i -lt 100 ]
do
...
...
done
echo "p=$(echo $p)" > tmp
echo "i=$(echo $i)" >> tmp
) | zenity --progress --title="test" --text="test"
. tmp
rm tmp
echo "i: $i p: $p"
これで、端末にi: 100 p: 10
ので、あなたの希望に応じてそれらを使用します。そして、あなたが最後の部分で尋ねたように、それはwhileループではなく、サブシェルです。サブシェルの内容を括弧で囲むのが習慣です。
プロセス置換は、迷惑なサブシェルの作成を防ぐことができますが、構文は少し奇妙です:
$ k=0; for x in a b; do ((k++)); done | zenity --progress; echo "$k"
→0(OKではない)
$ k=0; for x in a b; do ((k++)); done > >(zenity --progress); echo "$k"
→2(OK)
私が気に入っているのは、通常、スクリプトを適切に機能させるためにスクリプトを大幅に変更する必要がないことです。ただし、一部のエキゾチックなシェルにはこの機能が欠けている場合があります。 Bashについては、マニュアルの「Process Substitution」セクションを確認してください。
最初の質問の例により近いコードで:
i=0
p=0
while [ $i -lt 10 ]
do
i=$[$i + 1]
echo $((10 * i))
sleep 0.1
p=$[$p + 1]
done > >(zenity --progress --title="test" --text="test")
echo "i: $i p: $p"
(スリープを追加して進行をより目立たせ、i
を10回エコーして100
ループの終わりに達したとき。)