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"

删除同一行上的一个字符。因此,要在一行中数到十,您可以执行以下操作:

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 之后的行将不会执行。在单行上打印进度更新的标准方法是简单地使用\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 回答