Как ограничить количество строк, доступных для вывода команды в bash?

11

Я начал загружать большой файл в фоновом режиме, используя

$ nohup wget http://example.tld/big.iso &

который также дает мне nohup.outфайл, который включает в себя вывод wget.

Теперь, если я позже захочу наблюдать за процессом загрузки, я мог бы использовать, $ tail -f nohup.outно это заполняет окно моего терминала быстрее, чем я бы хотел. То, что я хотел бы видеть, - последняя строка, постоянно обновляющаяся (как при использовании в wgetодиночку).

Я пытался, $ tail -n 1 -f nohup.outно, похоже, влияет только на начальный хвост.

Вообще говоря, если можно ограничить (в данном случае до 1) количество строк, доступных для вывода / просмотра команды, это решило бы эту проблему. Что-то вроде вывода в кольцевом буфере - просто подумайте, что $ wget example.tld/big.isoбудет отображаться обычный индикатор выполнения .

Есть ли такое решение?

Или я забираюсь на дерево неправильно? (Имеется в виду, будет ли проще ограничить nohupвывод или сделать что-то еще?)

Яри ​​Кейнянен
источник

Ответы:

10

Если вы не хотите ограничивать область прокрутки (см. Мой другой ответ), вы также можете использовать возврат каретки, чтобы вернуться к началу строки перед печатью следующей строки. Существует escape-последовательность, которая очищает остальную часть строки, что необходимо, когда текущая строка короче предыдущей строки.

nohup wget http://cdimage.debian.org/debian-cd/6.0.3/amd64/iso-dvd/debian-6.0.3-amd64-DVD-1.iso &
el="$(tput el)"; # Clear to the end of the line
tail -n 1 -f nohup.out | while read -r line; do echo -n $'\r'"$el$line"; done;
janmoesen
источник
6

Вы можете использовать watchздесь:

watch -n 0.5 -e "tail -n 1 nohup.out"

Изменить : вариант -e(псевдоним --exec) выглядит здесь подходящим. Особенно, если вы стремитесь работать watchс очень небольшими интервалами, это уменьшает накладные расходы, вызванные sh -cвнутренним watchциклом в каждом цикле.

rozcietrzewiacz
источник
2
Обратите внимание, что это порождает новый tailпроцесс каждую секунду, который может или не может быть то, что вас волнует. Кроме того, обязательно укажите субсекундный интервал (например watch -n 0.1) для имитации «постоянно обновляемой» части. (Это, очевидно, увеличивает количество процессов и вызовов открытия файлов.) Наконец, если вы используете OS X, вы можете получить watchот MacPorts, так как он не доступен по умолчанию.
Янмезен
Это немного обходно, но замечательно как таковое. Я ожидал не полноэкранного ответа, чтобы увидеть предыдущие результаты - но на самом деле я мог бы использовать watchв новом окне терминала. Я также обнаружил, что использование tail -n 2более полезно, чем -n 1с wget, по крайней мере, с watchинтервалом в 1 секунду, потому что в противном случае последний процент может быть не виден; это не недостаток в вашем ответе, но я упомянул об этом, если кто-то решит посмотреть вывод wgets noiled-nohup.
Яри ​​Кейнянен
@janmoesen Для этого конкретного сценария наличие нового tailпроцесса, вероятно, не слишком излишне; но в качестве общего ответа это хорошо принять во внимание. Я также отметил, что watch -n 0.1это не работает, но watch -n 0,1работает - могут быть применены локали, хотя я раньше не видел, чтобы локали применялись к опциям команды терминала. В качестве примечания: также brew install watchотлично работал :-)
Яри ​​Кейнянен
Примечание: watchбудет ли работать с настройками локали 0,1или 0.1зависит от них (используется десятичный символ, определенный для вашей локали). Проверьте LC_ALL=C watch -n 0.1 "date +%S.%N".
rozcietrzewiacz
3

Существуют определенные управляющие последовательности Xterm, которые вы можете использовать для ограничения прокручиваемых линий вашего терминала. Ищите «Установить область прокрутки». Хотя это немного круто. После этого обязательно перезагрузите терминал:

nohup wget http://cdimage.debian.org/debian-cd/6.0.3/amd64/iso-dvd/debian-6.0.3-amd64-DVD-1.iso &
clear; echo -n $'\e[1;2r'; tail -f nohup.out | grep --line-buffered .
# The "grep" line is to ensure a single line; you can also use "awk 1" or "sed" etc.
janmoesen
источник
<Вставьте обычную заметку о
непереносимости
Это еще одна отличная альтернатива, но она также лучше всего используется в выделенном окне, так как она по- tail -fпрежнему заполняет буфер, а также потому, что терминал все равно требует перезагрузки. Это не так рядный , как я надеялся, но в противном случае это может быть то , что я искал.
Яри ​​Кейнянен
0

Если вы не хотите, чтобы вывод занимал все текущее окно терминала, вы можете использовать простой whileцикл:

while true; do 
  XXX=$( tail -n1 my.log )
  echo -en " \r$XXX\r"
  sleep 0.5
done; echo
rozcietrzewiacz
источник
1
Обратите внимание, что для возможности прокрутки вывода терминала во время выполнения любой команды, производящей вывод, вам необходимо отредактировать настройки эмулятора терминала и отключить scrollTtyOutput(или аналогичный) параметр.
rozcietrzewiacz