4

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)

2
  • Your while loop will run the command repeatedly, checking whether it was successful or not. Why do you think that syntax would check whether the first one is still running? Not to mention that you didn't run it in the background in the first place, that requires ending with &. Commented Jul 4, 2013 at 1:55
  • i know it doesnt work, its just an example of what i did before, and i added a desc. of what im trying to do at the bottom, its just an visual example Commented Jul 4, 2013 at 2:27

3 Answers 3

7
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 kill to test the sudo process itself, because you can't send signals to a process with a different uid.

Sign up to request clarification or add additional context in comments.

5 Comments

+1. Some notes in case POSIX conformance is desired: (1) echo -n . might print -n . followed by a newline instead of just . without a newline; printf . will always work as expected. (2) POSIX sleep only accepts integer seconds.
you seem to b on the right track to more of what im looking for, instead of the whiptail mentioned by the guy above... but i get this kill: Operation not permitted
i found something that seems to be exactly what im looking for, i haven't tried it yet but judging by its appearance theiling.de/projects/bar.html
yea, but i can make a script that asks to like, what does the user want to install like What would you want to install: eclipse then the script will automatically make the command valid? if that makes sense, like the script will take the users input and set it to this apt-get install eclipse --yes and yea... but use the bar syntax like "bar -o eclipse" or something idk
I don't think it will work, but feel free to give it a try. How is it supposed to know the progress percentage when there's no file whose size it can measure and compare with the current position?
4

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 $1}' | 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.

Comments

1

Whiptail is 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.

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

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

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

4 Comments

but whiptail is for message boxes. atleast thats all i see
A status bar is a form of message box.
This is clearly much more involved than the answer from @Barmer, but it's also much more robust, and prettier, and handles errors better, etc.
oh ok, ive seen that before.. mmm but i was looking forward to something more like this pastebin.com/0anEvtG7

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.