skip to Main Content

I want to inplement a progress bar use C like tqdm in Python or apt-get in Ubuntu. But I have no idea.

My problem is how to make the progress bar always be at the bottom of the terminal, and the top normally outputs something else.

Like the apt-get program in Ubuntu is implemented in the following figure.
enter image description here

2

Answers


  1. If I understand you are simply trying to find only the progress bar within the apt or apt-get code, so you can make use of it later, then there is no guarantee that it is named Progress:, or that the prompt containing Progress: is even in the script you are searching. It is likely sourced from another file.

    You can try opening the script in an editor like vim or kwrite or jot, etc. and looking within the script for where the meter is called and go from there. There is no telling whether it will be under scale, meter, percent, etc…

    In the absence of finding anything, you can always use something simple. There are many available on the web. Example:

    #!/bin/bash
    
    ## string of characters for meter (60 - good for 120 char width)
    str='▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒'
    
    tput civis                  # make cursor invisible
    
    for i in `seq 1 100`; do    # for 1 to 100, save cursor, restore, output, restore
        printf "33[s33[u Progress: %s %3d %% 33[u" "${str:0:$(((i+1)/2))}" "$i"
        sleep 0.1               # small delay
    done
    
    printf "33[K"             # clear to end-of-line
    
    tput cnorm                  # restore cursor to normal
    
    exit 0
    
    Login or Signup to reply.
  2. I made it in the form of a macro for direct use.

    #include <stdio.h>
    #include <unistd.h>
    
    #define START_PROGRESS_BAR(pbar, len) 
        char __##pbar[len] = {0};         
        memset(__##pbar, '#', sizeof(__##pbar) - 1)
    
    #define PROGRESS_BAR_RUNING(pbar, per, fmt, ...) ({                                       
        float p = per >= 100.0 ? 100.0 : per;                                                 
        int left = (p / 100.0) * (sizeof(__##pbar) - 1);                                      
        int right = (sizeof(__##pbar) - 1) - left;                                            
        printf("r[%.*s%*s] %.0f%%" fmt, left, __##pbar, right, "", (float)per, __VA_ARGS__); 
    })
    
    int main(int argc, char const *argv[])
    {
        START_PROGRESS_BAR(mybar, 64);
    
        for (int i = 0; i < 32; i++)
        {
            PROGRESS_BAR_RUNING(mybar, (float)i / 31 * 100.0, " %d KB/s", 105);
            usleep(100000);
        }
    
        return 0;
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search