2017-07-27 6 views
0

私は長いスクリプトの進捗状況を見て、出力しようとしています。 (後で進捗バーを計算するために進捗状況を使用したい)。while + pipeでbashのグローバル変数を使用していますか?

1 <-# before the first while) 
2 
3 
4 
5 
6 
7 
8 <-# end of first while) 
9 
10 
11 <-# end of second while) 

のような出力になり、私は今、期待する何

#!/bin/bash 

PROGRESS=0 

updateprogress() { 
    PROGRESS=$((PROGRESS + 1)) 
    echo $PROGRESS 
} 

<do something> 
updateprogress 

sudo cat /root/.virtualMachines | while read -r name ipAddr  # <-7 lines 
do 
    <do something> 
    updateprogress 
done 

sudo cat /root/.virtualServices | while read -r name ipAddr  # <-3 lines 
do 
    <do something> 
    updateprogress 
done 

しかし、私が得ることので問題はあり

1 <-# before first while) 
2 
3 
4 
5 
6 
7 
8 <-# end of first while 
2 
3 
4 <-# end of second while 

次のとおりです。ここで

が短縮例です。グローバル/ローカルスコープに関するものですが、どのようにグローバル変数$ PROGRESSのみを使うことができますか?すべての関数呼び出しについて?

+2

パイプが関与していますか?例えば。 'コマンド| while ... ' – choroba

+0

はい、確かに私の質問に更新します – derHugo

+0

あなたの質問に感謝;)私はあなたの入力と私は答え[ここ](https://stackoverflow.com/questions/16854280/ a-variable-modified-inside-while-while-loop-not-not-remembered) – derHugo

答えて

0

パイプは、渡されたinsctuctionsを実行する新しいコンテキストを作成します。あなたのコードに次の行を追加する場合は、警告が表示されます:

#beggining of your code ... 
#second while loop 
sudo cat /root/.virtualServices | while read -r name ipAddr (3 times) 
do 
    <do something> 
    updateprogress 
done 
echo $PROGRESS #will display '2' 

この問題に対処するには、次のように、パイプなしであなたのwhileループをリファクタリングする必要があります

while read -r name ipAddr 
do 
    #some instructions 
done < "path/to/the/file" 

使い方をストリームリダイレクションは新しいコンテキストを作成せず、期待した結果を生成します

+1

ちょっと感謝:)私はディテールを変更するだけでした:私はsudoを使用する必要があるので、これは 'done <<< (sudo cat /root/.virtualMachines) ' – derHugo

+0

これは回避策としてうまくいきます。さもなければ、あなたは私のバージョンを保持し、sudoでスクリプト全体を呼び出すことができます。うまくいくはずです。ただし、ファイルのアクセス権を昇格された権限でのみ実行し、残りのスクリプトでは実行しないようにするには、バージョンを保持してください。 – Aserre

+0

だから、私はこれを後でこのように使うつもりです。私はまだそれを書いていて、いくつかのファイルを削除していますし、すべてをrootとして実行したくないのです。 Butanywayあなたの助けに感謝!今はうまく動作します – derHugo

関連する問題