2013-02-09 39 views
0

我目前正在編寫一個bash腳本來自動執行任務。在我的腳本中,我希望它在執行任務時顯示進度消息。bash腳本中任務的自定義進度消息

例如:

用戶@ Ubuntu的:〜$配置一些

- >

配置的東西。

- >

配置東西..

- >

配置的東西...

- >

配置的東西...做

所有進度消息應該出現在同一直線上。 下面是我的解決方法到目前爲止:

echo -n "Configure something " 
exec "configure something 2>&1 /dev/null" 
//pseudo code for progress message 
echo -n "." and sleep 1 if the previous exec of configure something not done 
echo " done" if exec of the command finished successfully 
echo " failed" otherwise 

將Exec的等待命令完成,然後與後來的劇本線繼續下去嗎? 如果是這樣,那麼我怎麼可以在配置事件的exec的同時發送消息? 我如何知道exec何時完成前面的命令並返回true?使用$?

回答

1

只是爲了編輯帽子,如果出現什麼問題怎麼辦?你好,或你的腳本的用戶會知道什麼出錯了?這可能不是您正在尋找的答案,但讓您的腳本單獨執行每個構建步驟可能會變得更好,尤其是對於故障排除。爲什麼不定義一個函數來驗證您構建步驟:

function validateCmd() 
{ 
    CODE=$1 
    COMMAND=$2 
    MODULE=$3 

    if [ ${CODE} -ne 0 ]; then 
    echo "ERROR Executing Command: \"${COMMAND}\" in Module: ${MODULE}" 
    echo "Exiting." 
    exit 1; 
    fi 
}  

./configure 
validateCmd $? "./configure" "Configuration of something" 

不管怎麼說,是因爲你可能注意到上述情況,使用$?,以確定哪些最後一個命令的結果。例如:

rm -rf ${TMP_DIR} 

if [ $? -ne 0 ]; then 
    echo "ERROR Removing directory: ${TMP_DIR}" 
    exit 1; 
fi 

要回答你的第一個問題,你可以使用:

echo -ne "\b" 

要在同一行中刪除字符。因此,要數到十一個行了,你可以這樣做:

for i in $(seq -w 1 10); do 
    echo -en "\b\b${i}" 
    sleep .25 
done 
echo 

與訣竅是你必須知道多少刪除,但我敢肯定你能明白這一點。

+0

謝謝。你是對的,我不應該把所有的stdout和stderr都指向null,而是指向一些日誌文件。 – 2013-02-09 05:08:28

+0

'cmd;如果[$? -ne 0];那麼foo'更好,更習慣寫法'if! CMD;那麼foo' – tripleee 2013-02-09 08:18:42

1

不能調用exec那樣; exec永遠不會返回,exec之後的行將不會執行。要在一行上打印進度更新的標準方法是簡單地使用\r,而不是\n在每行的末尾。例如:

#!/bin/bash 

i=0 
sleep 5 & # Start some command 
pid=$!  # Save the pid of the command 
while sleep 1; do # Produce progress reports 
    printf '\rcontinuing in %d seconds...' $((5 - ++i)) 
    test $i -eq 5 && break 
done 
if wait $pid; then echo done; else echo failed; fi 

再舉一例:

#!/bin/bash 

execute() { 
    eval "[email protected]" & # Execute the command 
    pid=$! 

    # Invoke a shell to print status. If you just invoke 
    # the while loop directly, killing it will generate a 
    # notification. By trapping SIGTERM, we suppress the notice. 
    sh -c 'trap exit SIGTERM 
    while printf "\r%3d:%s..." $((++i)) "$*"; do sleep 1 
    done' 0 "[email protected]" & 
    last_report=$! 
    if wait $pid; then echo done; else echo failed; fi 
    kill $last_report 
} 
execute sleep 3 
execute sleep 2 \| false # Execute a command that will fail 
execute sleep 1 
+0

這種方法優於我以前使用的方法。謝謝! – Anew 2013-02-09 06:02:41