【问题标题】:Bash progress bar when running commands from within a script从脚本中运行命令时的 Bash 进度条
【发布时间】:2016-12-18 11:34:15
【问题描述】:

我正在编写一个 bash 脚本来执行东西的安装。

我不希望用户看到命令及其输出,所以我将使用2>&1 重定向它们。

我确实希望为完成安装的每个部分打印一个进度条,并根据是否有错误显示成功/失败消息,例如:

Installing OpenCv ..................... [Success]
Installing Qt     ..................... [Failed]

这是我的代码:

#!/bin/bash

installOf="Installing OpenCv  "

function printProgressBar() 
{
    local progressBar="."
    printf "%s" "${progressBar}"
}

function InstEssent
{
    sudo apt-get -y install build-essential
    sleep 5
    echo "Done"
}

printf "%s" "${installOf}"

InstEssent  &

while [ "${InstEssent}" != "Done" ]
do
    printProgressBar 
    sleep 1
done

installStatus="Success"
printf " [%s]\n" "${installStatus}"

【问题讨论】:

  • 我相信您已经在其他地方看到过这种做法,那么您为什么不认为这是可能的呢?
  • 你的代码在哪里?
  • @Inian:对不起,我病了,没时间看。现在正在这样做,很快就会更新,抱歉。

标签: linux bash ubuntu io progress-bar


【解决方案1】:

好吧,bash 或我知道的其他 shell 中没有本机工具,但您可以使用下面的 printf 和此自定义函数来实现您的需要。这个小 sn-p 将打印安装进度条,您可以通过普通函数调用 printProgressBar 在脚本中您想要显示它的各个位置打印它。

function printProgressBar() {
    local progressBar="."
    printf "%s" "${progressBar}"
}

假设您的函数调用中有n 步骤,请将此函数调用插入到两者之间的位置。对于错误消息的实际打印,请在变量installOf 中填充安装标头,假设您的示例可以采用"Installing OpenCv "(或)"Installing Qt ",请在步骤之前在此变量中使用它

installOf="Installing OpenCv  "
printf "%s" "${installOf}"

对于最终状态,由于您没有让我们知道您如何获得安装的整体状态,假设您根据成功或失败找到它,请在另一个变量中更新它

installStatus="Success"
printf " [%s]\n" "${installStatus}"

综上所述,我有一个简单的 while 循环,它运行该函数进行 20 次调用,您可以使用类似的方式在脚本中的不同位置采用您的函数调用。

installOf="Installing OpenCv  "

function printProgressBar() {
    local progressBar="."
    printf "%s" "${progressBar}"
}

printf "%s" "${installOf}"

while (( cnt < 20))
do
    ((cnt++))
    printProgressBar 
    sleep 1
done

# You can determine the status of your installation as your script demands

installStatus="Success"
printf " [%s]\n" "${installStatus}"

运行脚本会产生与您的要求相似的结果,

$ bash script.sh
Installing OpenCv  .................... [Success]

注意,每个. 代表一个函数调用的每个实例。

更新:-

查看您的代码逻辑,您忽略了后台作业的工作原理。您在安装某个模块时的后台功能InstEssent。要有效地使用进度条,您需要使用kill -0 "$pid" 命令不断轮询后台作业以查看它是否仍在运行,如果它正在运行,请按以下代码所示打印安装栏。

function InstEssent()
{
    sudo apt-get -y install build-essential
    sleep 5
}

printf "%s" "${installOf}"

InstEssent  &
pid_InstEssent="$!"

while kill -0 "$pid" 2> /dev/null
do
    printProgressBar 
    sleep 1
done

【讨论】:

  • 我尝试实施您的解决方案。点的打印效果很好。但是,似乎我无法从函数中更改全局变量。那是对的吗?我希望我的函数更改一个“停止”变量以指示进度条根据安装进度停止。
  • @Idanis:感谢您尝试我的逻辑,您能用一些实际代码解释更多关于您看到的问题吗?乍一看似乎有点微不足道。也许这个页面可以帮助你解决你面临的问题,stackoverflow.com/questions/23564995/…
  • 感谢您的回复。我在上面更新了我的代码。当我运行这段代码时,我根本看不到任何点,函数完成运行,打印“完成”,然后脚本退出并显示“成功”消息。这就是我想要实现的目标:我试图“在后台”运行这个函数并打印点直到它完成。完成后,我希望打印成功/失败消息。我在这里遗漏了一些东西,但我只是不知道是什么..
猜你喜欢
  • 1970-01-01
  • 2016-10-20
  • 1970-01-01
  • 2015-01-09
  • 1970-01-01
  • 1970-01-01
  • 2013-01-21
  • 2013-12-07
  • 1970-01-01
相关资源
最近更新 更多