альтернатива tail -f, которая не прокручивает окно терминала - PullRequest
5 голосов
/ 13 января 2011

Я хочу регулярно проверять файл на предмет содержания, которое постоянно меняется. «tail -f» не достаточно, так как размер файла не увеличивается.

Я мог бы использовать простой цикл while в bash для того же эффекта:

while [ 1 ]; do cat /proc/acpi/battery/BAT1/state ; sleep 10; done

Это работает, хотя и имеет нежелательный эффект прокрутки окна моего терминала.

Так что теперь мне интересно, есть ли команда linux / shell, которая отображала бы вывод этого файла без прокрутки терминала?

Ответы [ 5 ]

12 голосов
/ 13 января 2011
watch -n 10 cat /proc/acpi/battery/BAT1/state

Вы можете добавить флаг -d, если хотите, чтобы он выделил различия от одной итерации к следующей.

9 голосов
/ 13 января 2011

watch твой друг.Он использует проклятия, поэтому он не будет прокручивать ваш терминал.

Usage: watch [-dhntv] [--differences[=cumulative]] [--help] [--interval=<n>] [--no-title] [--version] <command>
  -d, --differences[=cumulative]        highlight changes between updates
                (cumulative means highlighting is cumulative)
  -h, --help                            print a summary of the options
  -n, --interval=<seconds>              seconds to wait between updates
  -v, --version                         print the version number
  -t, --no-title                        turns off showing the header

Итак, на вашем примере это будет:

watch -n 10 cat /proc/acpi/battery/BAT1/state
6 голосов
/ 13 января 2011

Объединение нескольких идей из других ответов плюс пара других трюков позволяет вывести файл без очистки экрана или прокрутки (за исключением первого цикла, если подсказка находится внизу экрана).

up=$(tput cuu1)$(tput el); while true; do (IFS=$'\n'; a=($(</proc/acpi/battery/BAT1/state)); echo "${a[*]}"; sleep 1; printf "%.0s$up" ${a[@]}); done

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

watchit () {
    local up=$(tput cuu1)$(tput el) IFS=$'\n' lines
    local start=${3:-0} end
    while true
    do
        lines=($(<"$1"))
        end=${4:-${#lines[@]}}
        echo "${lines[*]:$start:$end}"
        sleep ${2:-1}
        # go up and clear each line
        printf "%.0s$up" "${lines[@]:$start:$end}"
    done
}

Запустите его:

watchit /proc/acpi/battery/BAT1/state .5 0 6

Второй аргумент (секунды между обновлениями) по умолчанию равен 1. Третий аргумент (начальная строка) по умолчанию равен 0. Четвертый аргумент (количество строк) по умолчанию используется для всего файла. Если вы опустите количество строк и файл увеличится, это может привести к прокрутке для размещения новых строк.

Редактировать: Я добавил аргумент для контроля частоты обновлений.

3 голосов
/ 13 января 2011

Канонический (и самый простой, и самый гибкий) ответ - watch, как говорили другие.Но если вы хотите увидеть только первую строку файла, вот альтернатива, которая не очищает и не прокручивает терминал:

while line=`head -n 1 /proc/acpi/battery/BAT1/state` \
    && printf "%s\r" "$line" \
    && sleep 10
do
    printf "%s\r" "`echo -n "$line" | sed 's/./ /g'`"
done
echo

Возврат каретки является основной концепцией.Он указывает курсору вернуться к началу текущей строки, как новая строка, но без перехода на следующую строку.Здесь используется команда printf, потому что (1) она не добавляет автоматически новую строку, и (2) она переводит \r в возврат каретки.

Первый printf печатает вашу строку.Второй очищает его, перезаписывая его пробелами, так что вы не видите мусора, если следующая строка для печати короче.

Обратите внимание, что если напечатанная строка длиннее ширины вашего терминала,терминал все равно будет прокручиваться.

3 голосов
/ 13 января 2011

Мой любимый, который работает в местах, где нет watch, это:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...