2013-06-04 160 views
5

我想在我的腳本中編寫一個循環「請稍候」消息的進度指示器函數,直到完成調用它的任務。如何在shell腳本中顯示進度指示器功能?

我希望它是一個函數,以便我可以在其他腳本中重用它。

爲了達到這個目的,函數需要與其他函數鬆散耦合,即調用它的函數不需要知道它的內部代碼。

這是我到目前爲止。這個函數接收調用者的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 

問題是,當我把它從另一個函數,函數沒有pids:

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 oriented menu system。

進度條可以檢查http://bash.cyberciti.biz/guide/A_progress_bar_(gauge_box)

,或者另一種更簡單的項目: http://www.theiling.de/projects/bar.html

如果不感興趣,你可以嘗試下:

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()函數之外殺死它.​​.....也許這不能用shell腳本來完成。謝謝! – Tarek

+0

嗨,我已經試過提供的代碼,但它遭受同樣的問題,因爲程序完成時發送SIGTERM。除非我明確發送kill信號,否則我不能在函數內部使用它。 – Tarek

+1

@Tarek真的不明白你的意思是「在函數內部」和「除非發送殺手」......但是:我編輯了腳本以顯示如何在一個函數內使用它,對於第二個,當然你__need__發送信號 - 你必須告訴後臺進程:「立即停止」...。如果你的意思是其他的 - 不能幫助... – jm666

1

通過在後臺運行它,你得到它的輸出與代碼的其餘部分混合,所以你一定不能輸出任何東西在別處,而progress運行。

要實現它作爲函數,當進度應該終止時,您需要一個全局變量來控制(當調用它時,可以將變量的名稱作爲arg傳遞給progress)。

+0

感謝,而是一個全局變量是行不通的,因爲它不會在函數內部改變。 – Tarek

+0

是的。這就是shell腳本的工作原理。函數沒有返回值,你也必須使用全局變量。 – yaccz

+0

你在說出口變量嗎?因爲我昨天快速測試: PARAM = 「測試」 功能測試(){ 回聲$ 1 睡眠5 回聲$ 1 \t回聲$ {PARAM} } 測試$ {PARAM}& PARAM = 「改變」 等待$ 1 回聲$ {} PARAM 輸出爲: $測試 $測試 $測試 $改變 也許我誤解你的意思與全局變量。 – Tarek

1

我聽說過這個project。我沒有使用它,所以不知道它是多麼容易集成,但你可以給它一個閱讀。

+0

謝謝!我不需要任何先進的東西(只是在程序執行時「請稍候...」)。我要看看代碼。 – Tarek

0

遺憾的是我沒」能夠使用shell腳本來做我想要的。下面是我做了什麼:

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

用法:

aguarde & 
dotpid=$! 
# code 
eval "kill ${dotpid}"