Создание прогресса в Bash фиксируется в нижней части терминала

Это добавит 10:

echo "$(awk '{x=$0+10;if(x>100)x=100; print x}' a.txt)" > a.txt

Это вычтет 10:

echo "$(awk '{x=$0-10;if(x<0)x=0; print x}' a.txt)" > a.txt

$ 0 - это значение текущей строки, читаемой в файле , поэтому он добавляет / вычитает 10 из него, а затем проверяет, находится ли он в пределах ограничений.

Благодаря замечательному комментарию Wildcard, вы можете сделать это без использования временного файла.

3
12.09.2018, 20:06
3 ответа

Возможно, но я думаю, что это будет сложнее, чем вы ожидаете.

Вы можете заставить курсор перемещаться по терминалу, выводя управляющие коды ANSI. Подробнее о них см. здесь .

В принципе, вы можете переместить курсор на индикатор выполнения, добавить =, а затем переместить его обратно туда, где вы планируете распечатать вывод. Затем на следующем =вам придется сделать это снова... но это, вероятно, будет некрасиво.

Если вы хотите отказаться от bash, вы, вероятно, можете найти библиотеки, которые упрощают подобные вещи, (например, this).

3
27.01.2020, 21:09

Я написал тестовый скрипт, чтобы попытаться сделать то, что предложил @MatrixManAtYrService. Я понял, что это решение применимо не ко всем системам, на которые распространяется U&L SE, но оно работает в соответствии со спецификациями, которые я запросил.

#!/bin/bash

# go to last line and print the empty progress bar
tput sc #save the current cursor position
tput cup $((`tput lines`-1)) 3 # go to last line
echo -n "[" # the next 5 lines just print the required stuff to make the bar
for i in $(seq 1 $((`tput cols`-10))); do
    echo -n "-"
done
echo -n "]"
tput rc # bring the cursor back to the last saved position


# the actual loop which does the script's main job
for i in $(seq 0 10 100); do
    # print the filled progress bar
    tput sc  #save the current cursor position
    doned=${i}  #example value for completed amount
    total=100   #example value for total amount

    doned=`echo $doned $total | awk '{print ($1/$2)}'` # the next three lines calculate how many characters to print for the completed amount
    total=`tput cols | awk '{print $1-10}'`
    doned=`echo $doned $total | awk '{print int(($1*$2))}'`


    tput cup $((`tput lines`-1)) 4 #go to the last line
    for l in $(seq 1 $doned); do #this loop prints the required no. of "="s to fill the bar
        echo -n "="
    done
    tput rc #bring the cursor back to the last saved position

    # the next 7 lines are to find the row on which the cursor is currently on to check if it 
    # is at the last line 
    # (based on the accepted answer of this question: https://stackoverflow.com/questions/2575037/)
    exec < /dev/tty
    oldstty=$(stty -g)
    stty raw -echo min 0
    tput u7 > /dev/tty
    IFS=';' read -r -d R -a pos
    stty $oldstty
    row=$((${pos[0]:2} - 1))


    # check if the cursor is on the line before the last line, if yes, clear the terminal, 
    # and make the empty bar again and fill it with the required amount of "="s
    if [ $row -gt $((`tput lines`-2)) ]; then
        clear
        tput sc
        tput cup $((`tput lines`-1)) 3
        echo -n "["

        for j in $(seq 1 $((`tput cols`-10))); do
            echo -n "-"
        done
        echo -n "]"
        tput cup $((`tput lines`-1)) 4
        for k in $(seq 1 $doned); do
            echo -n "="
        done
        tput rc
    fi

    # this is just to show that the cursor is behaving correctly
    read -p "Do you want to continue? (y/n)" yn;  

done

 # the next few lines remove the progress bar after the program is over   
tput sc # save the current cursor position
tput cup $((`tput lines`-1)) 3 # go to the line with the progress bar
tput el # clear the current line
tput rc # go back to the saved cursor position

Должны быть лучшие способы обработки переполнения в последней строке вместо очистки терминала, среди прочего. Это больше служит доказательством концепции того, что предложил @MatrixManAtYrService. Любые улучшения или комментарии по его ограничениям приветствуются

5
27.01.2020, 21:09

Простой способ получить индикаторы выполнения в сценарии оболочки — использовать whiptail или диалоговое окно, как упоминалось в комментариях. Один или оба должны быть доступны в большинстве дистрибутивов Linux.

ОП упомянул в комментариях установщик aptitude. Aptitude — это двоичный файл, который использует библиотеку ncurses, как и диалог.

2
27.01.2020, 21:09

Теги

Похожие вопросы