Мое намерение состоит в том, чтобы вывести журнал рекурсивного wget
в одну строку, похожую на строку состояния. Поэтому я собрал этот конвейер (мой вызов wget
имеет немного больше опций, но я оставил только те, которые необходимы для описанной проблемы):
wget -r -nv ftp://example.com 2>&1 | cut -c1-80 | xargs -I line echo -ne 'line\033[0K\r'
Позвольте мне объяснить, что я хотел сделать. Может быть, что-то не так с моей командой.
-r
означает «рекурсивная загрузка»;
-nv
делает сообщения о каждой загрузке краткими, например: "time: URL -> local file";
&2>1
перенаправляет stderr на стандартный вывод, чтобы я мог работать с сообщениями по каналам;
| cut -c1-80
обрезает строку вывода до 80 символов. Иногда URL и имя локального файла вместе образуют длинную строку, которая разбивает строку на 2 или более. И мне нужно, чтобы он уместился в одной строке консоли. 80 стоит здесь только для примера. В моем сценарии я определяю ширину консоли с помощью tput cols
;
| xargs -I line echo -ne 'line\033[0K\r'
печатает выходные данные предыдущей команды и добавляет два специальных символа: \033[OK
- конец строки, который очищает оставшуюся часть строки, если от вывода prevoius остались какие-либо символы; и \r
- возврат каретки, который устанавливает курсор на начало текущей строки.
Итак, требуемое поведение:
wget
загружает файл и пытается напечатать уведомление об этом на стандартный вывод
cut
немедленно перехватывает вывод wget и обрезает его до 80 символов
xargs
ловит обрезанную линию и печатает ее немедленно со специальными символами
Так что я должен увидеть какую-то строку состояния, где отображается текущая загрузка.
Но! Все, что я вижу, это то, что ничего не происходит в течение 10–60 секунд, а затем все сообщения о загрузках, которые были сделаны в течение этого времени, печатаются в течение приблизительно 1 секунды. Они на самом деле печатали так, как я хотел, но очень быстро. Затем снова пауза, очередная порция сообщений через 1 секунду и так далее. Так что все в порядке, кроме сразу -несс.
Когда я удаляю часть xargs
, сообщения отображаются мгновенно (но не в одной строке). Когда я удаляю вызов cut
, они выполняются мгновенно, но иногда строка разрывается с каким-то действительно длинным URL. Если я удаляю только специальные символы из echo
, то вызов по-прежнему будет "нервным", а не в одной строке.
Чтобы воспроизвести это, вы можете заменить «ftp://example.com» на любой URL (HTTP также будет работать), который можно использовать для тестирования рекурсивной загрузки, т. Е. В случае, если FTP имеет много файлов и каталогов, а в случае HTTP имеет много ссылок на страницы, на которых есть больше ссылок (не бойтесь, что он может попытаться загрузить весь Интернет, поскольку опция -r
по умолчанию имеет уровень рекурсии по умолчанию 5). Если вы не можете воспроизвести это, я полагаю, что-то не так с моим дистрибутивом, пожалуйста, напишите об этом в разделе комментариев ниже.
P.S. Если вы знаете лучший способ организации строки состояния для wget
, ваши комментарии очень приветствуются. Но я изучаю Bash и хотел бы знать, что вызывает такое странное поведение. Может быть, есть что-то о трубах или echo
или xargs
Я не знаю. Поэтому вопрос в том, почему этот конвейер работает так, а не так, как я ожидал.