Получаем список установленных в Debian пакетов, часть вторая

debianeach

Опубликован:  2019-10-13T07:58:46.281013Z

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

Итак, мне необходимо получить список установленных в моём Debian buster пакетов, и каждая строчка этого списка должна содержать только имя пакета. Команда, позволяющая решить задачу в моей конкретной системе, выглядит следующим образом:

dpkg -l | cut -c5-50 | tail -2528 | sed -e 's/:amd64//' -e 's/:i386//' -e 's/  *$//' > packages

На первый взгляд, всё замечательно работает, но, поскольку Дебианыч перфекционист, даже в самом изящном решении он всегда ищет место подвигу. В предложенной при решении задачи команде есть блок команды tail, и именно эту часть команды я попытаюсь модифицировать.

Дело в том, что параметр программы tail задан целой константой, а именно:

tail -2528

Для моей системы эта константа имеет смысл, потому что команда dpkg -l выдаёт 2535 строк, из которых 7 строк - шапка выхлопа, а остальные 2528 строк - целевые данные, которые необходимо получить и обработать по условию задачи. Чтобы унифицировать решение для любой другой подобной системы, но с другим количеством установленных в той системе пакетов, эту константу необходимо заменить некоторым выражением. Это выражение я сейчас и буду получать при помощи пошаговой интерактивной отладки.

Интерпретатор bash умеет считать выражения с целыми числами. Давайте посмотрим, как в терминале получить заветное число 2528.

echo $((2535 - 7))

McnbE3EQwd.png

Все мы помним, каким образом получилось число 2535 в моей системе.

dpkg -l | wc -l

70P39TTycu.png

А что, если в первую команду подставить вместо числа 2535 выхлоп второй команды? Давайте попробуем...

echo $(($(dpkg -l | wc -l) - 7))

WnCUl6n36i.png

Великолепно! Как видно на снимках экрана, знак доллара$ обладает в терминале просто какой-то магической силой. С помощью этой магической силы я теперь могу подставить полученное выражение в аргумент программе tail своей целевой команды.

dpkg -l | tail -$(($(dpkg -l | wc -l) - 7)) | less

98UrfP5cFh.png

lwdhIyIUw4.png

Состав списка не изменился, наименования первого и последнего пакетов на снимках экрана выше показывают это. Теперь достаточно дополнить команду последовательно программными каналами с cut и sed, чтобы получить итоговую искомую команду, решающую поставленную задачу.

dpkg -l | tail -$(($(dpkg -l | wc -l) - 7)) | cut -c5-50 | sed -e 's/:i386//' -e 's/:amd64//' -e 's/  *//' > packages

Lc0KN43MkP.png

В таком виде эту команду можно переносить на любую deb-совместимую систему с той же версией dpkg, в теле команды осталась константа 7, которая определяет количество строк в "шапке" выхлопа dpkg.

В качестве вывода... Терминал Linux - весьма продвинутый инструмент, позволяющий простыми движениями решать достаточно сложные задачи, но требует при этом начальной теоретической подготовки. Для изучения основ продвинутой работы в терминале Дебианыч рекомендует хорошую книжку: Stephen G. Kochan, Patrick Wood. Shell Programming in Unix, Linux and OS X.

Комментарии: