bash Linux Shell,在后台运行命令时显示一些内容

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17460737/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 05:50:09  来源:igfitidea点击:

Linux Shell, display something while a command is running in the background

linuxbashshell

提问by xR34P3Rx

I want to make a short script, just for experiment purposes. For example, I run a command such as

我想制作一个简短的脚本,仅用于实验目的。例如,我运行一个命令,如

sudo apt-get install eclipse --yes

and instead of displaying the verbose of the command while its installing it, display a loading bar like ...... (dots just popping up while it loads or something)

而不是在安装时显示命令的详细信息,而是显示一个加载栏,例如......(加载时会弹出点或其他东西)

I tried doing something like

我尝试做类似的事情

apt=sudo apt-get install vlc --yes

start()
{
    $apt
    while $apt;
    do
        echo -n "."
        sleep 0.5
    done
}
start

(what I intended to do was to run the $apt variable and then make it move on to the while loop and the while loop will determine if the command is running, so while the command is running it will replace the verbose with dots)

(我打算做的是运行 $apt 变量,然后让它移动到 while 循环,while 循环将确定命令是否正在运行,因此在命令运行时,它将用点替换冗长)

回答by Barmar

apt-get install vlc --yes >/tmp/apt-get.log & # Run in background, with output redirected
pid=$! # Get PID of background command
while kill -0 $pid  # Signal 0 just tests whether the process exists
do
  echo -n "."
  sleep 0.5
done

Put the above in a script and run it via sudo. You can't use killto test the sudoprocess itself, because you can't send signals to a process with a different uid.

将上述内容放入脚本中并通过sudo. 您不能用于kill测试sudo进程本身,因为您不能向具有不同 uid 的进程发送信号。

回答by wizurd

Here's a small variation on the ones above...

这是上面那些的一个小变化......

spinner()
{
    local pid=$!
    local delay=0.75
    local spinstr='...'
    echo "Loading "
    while [ "$(ps a | awk '{print }' | grep $pid)" ]; do
        local temp=${spinstr#?}
        printf "%s  " "$spinstr"
        local spinstr=$temp${spinstr%"$temp"}
        sleep $delay
        printf "\b\b\b"
    done
    printf "    \b\b\b\b"
}

with usage:

用法:

(a_long_running_task) &
spinner

This prints out

这打印出来

Loading ...

Loading ....

Loading .....

Loading ......

正在加载...

加载中....

加载中.....

加载中......

On the same line of course.

当然在同一条线上。

回答by Flimzy

Whiptailis a tool to do this for you. It is fairly easy to make it display a progress bar, or other information, for you, while your task completes.

Whiptail是为您执行此操作的工具。当您的任务完成时,让它为您显示进度条或其他信息是相当容易的。

In fact, it's the tool used by Debian, and many other distributions, in exactly the same context you're using.

事实上,它是 Debian 和许多其他发行版使用的工具,与您使用的环境完全相同。

Here's a simplified version of the code we use to make aptitude installs friendlier looking:

这是我们用来使 aptitude 安装看起来更友好的代码的简化版本:

pkg=0
setterm -msg off # Disable kernel messages to this terminal
setterm -blank 0 # Disable screen blanking
aptitude -y install <list of packages> | \
    tr '[:upper:]' '[:lower:]' | \
while read x; do
    case $x in
        *upgraded*newly*)
            u=${x%% *}
            n=${x%% newly installed*}
            n=${n##*upgraded, }
            r=${x%% to remove*}
            r=${r##*installed, }
            pkgs=$((u*2+n*2+r))
            pkg=0
        ;;
        unpacking*|setting\ up*|removing*\ ...)
            if [ $pkgs -gt 0 ]; then
                pkg=$((pkg+1))
                x=${x%% (*}
                x=${x%% ...}
                x=$(echo ${x:0:1} | tr '[:lower:]' '[:upper:]')${x:1}
                printf "XXX\n$((pkg*100/pkgs))\n${x} ...\nXXX\n$((pkg*100/pkgs))\n"
            fi
        ;;
    esac
done | whiptail --title "Installing Packages" \
        --gauge "Preparing installation..." 7 70 0
setterm -msg on # Re-enable kernel messages
invoke-rc.d kbd restart # Restore screen blaking to default setting