0

現在、タスクを自動的に実行するための bash スクリプトを作成しています。私のスクリプトでは、タスクを実行しているときに進行状況メッセージを表示したいと考えています。

例えば:

user@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 が前のコマンドを終了して true を返すタイミングを知るにはどうすればよいですか? 使用し$?ますか?

4

2 に答える 2

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"

同じ行の文字を削除します。したがって、1 行で 10 まで数えるには、次のようにします。

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

そのトリックは、削除する量を知る必要があることですが、それを理解できると確信しています.

于 2013-02-09T04:49:36.540 に答える
1

そのように呼び出すことはできませんexec。exec は戻らず、exec の後の行は実行されません。進行状況の更新を 1 行に出力する標準的な方法は、単に各行の最後で\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 "$@" &  # 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 "$@" &
    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
于 2013-02-09T05:55:49.073 に答える