我正在编写一个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?使用$?
?
答案 0 :(得分: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
这样做的诀窍是你必须知道要删除多少,但我相信你可以搞清楚。
答案 1 :(得分: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