2013-06-04 2 views
5

スクリプト内に進捗インジケータ関数を記述して、呼び出されたタスクが完了するまで「しばらくお待ちください」というメッセージをループします。シェルスクリプトに進捗インジケータ機能を表示するにはどうすればよいですか?

私はそれを他のスクリプトで再利用できるように関数にしたいです。

これを達成するには、関数を他の関数と疎結合する必要があります。つまり、呼び出す関数が内部コードを知る必要はありません。

これまで私がこれまで持っていたことは次のとおりです。この関数は、呼び出し元のpidを受け取り、タスクが終了するまでループします。

function progress() { 
    pid="$1" 

    kill -n 0 "${pid}" &> /dev/null && echo -ne "please wait" 
    while kill -n 0 "${pid}" &> /dev/null ; do 
    echo -n "." 
    sleep 1 
    done 
} 

スクリプトでそれを使用する場合、それはのような、正常に動作します:出力

#imports the shell script with the progress() function 
. /path/to/progress.sh 

echo "testing" 
# $$ returns the pid of the script. 
progress $$ & 
sleep 5 
echo "done" 

:私は別の関数からそれを呼び出すとき

$ testing 
$ please wait..... 
$ done 

問題は関数として、ありますpidがありません:

function my_func() { 
    progress $$ & 
    echo "my func is done" 
} 

. /path/to/progress.sh 
echo "testing" 
my_func 
sleep 10 
echo done 

出力:

$ testing 
$ please wait..... 
$ my func. is done. 
$ .......... 
$ done 

答えて

2

dialog - bash curses指向のメニューシステムに興味があるかもしれません。 「

dotpid= 
rundots() { (trap 'exit 0' SIGUSR1; while : ; do echo -n '.' >&2; sleep 0.2; done) & dotpid=$!; } 
stopdots() { kill -USR1 $dotpid; wait $dotpid; trap EXIT; } 
startdots() { rundots; trap "stopdots" EXIT; return 0; } 

longproc() { 
    echo 'Start doing something long... (5 sec sleep)' 
    sleep 5 
    echo 
    echo 'Finished the long job' 
} 

run() { 
    startdots 
    longproc 
    stopdots 
} 

#main 
echo start 
run 
echo doing someting other 
sleep 2 
echo end of prog 
+0

これは私の以前の試みに近いですが、私はprogress()関数の外でそれを削除することを避けようとしていました...しかし、おそらくシェルスクリプトではできません。ありがとう! – Tarek

+0

こんにちは、提供されたコードを試しましたが、プログラムが完了したときにSIGTERMが送信されるため、同じ問題が発生します。 killシグナルを明示的に送信しない限り、関数内で使用することはできません。 – Tarek

+1

@Tarekは、 "関数内"と "killを送信しない限り"とはどういう意味なのですか?:しかし、関数内での使用方法を示すスクリプトを編集しました。 __need__はシグナルを送ります - あなたはバックグラウンドプロセスに何かを伝える必要があります: "今停止" ...。あなたが他の何かを意味するなら - 助けてはいけない... – jm666

1

バックグラウンドでそれを実行することによって、あなたはそれがコードの残りの部分と混合して出力のget、あなたがprogressの実行中に別の場所で何も出力してはいけません。

これを関数として実装するには、プログレスを終了する必要があるときにグローバル変数を制御する必要があります(呼び出し時に変数名をprogressに渡すことができます)。

+0

おかげで、それは関数内で変更されないよう、グローバル変数は、動作しないでしょう。 – Tarek

+0

はいそうです。それがシェルスクリプトの仕組みです。関数は戻り値を持たないので、グローバル変数も使用する必要があります。 – yaccz

+0

変数のエクスポートについて話していますか?私は昨日、簡単なテストをしたので: のparam = "テスト" 機能テスト(){ は$ 1 睡眠をエコー5 は$ 1 \tエコーエコー$ {のparam} } テスト$ {のparam}& のparam = $テスト $テスト $テストは $は、おそらく私はあなたがグローバル変数に何を意味するのか誤解 を変更:$ 1 が出力された$ {のparam} をエコー待つ 「変更」 – Tarek

1

これについて聞いたことがありますproject。私はそれを使用していないので、どのように簡単に統合するのかはわかりませんが、あなたはそれを読むことができます。

+0

ありがとう!私は高度なものは必要ありません(プログラムが実行されている間はちょうど「お待ちください...」)。私はコードを見てみるつもりです。 – Tarek

0

は、悲しいことに、私はwasn:あなたは、次を試すことができ、 http://www.theiling.de/projects/bar.html

興味を持っていない場合:

プログレスバーのためには、http://bash.cyberciti.biz/guide/A_progress_bar_(gauge_box)

または、別の単純なプロジェクトを確認することができますシェルスクリプトを使って欲しいことをすることができます。

function progress() { 
    echo -ne "please wait" 
    while : 
    do 
    echo -n '.' 
    sleep 1 
    done 
} 

使用方法:ここで私がやったものだ

aguarde & 
dotpid=$! 
# code 
eval "kill ${dotpid}" 
関連する問題