Как мне перечислить команды, которые предоставляет пакет? [дубликат]

Я Любопытно, какие команды в моей системе предоставляет определенный пакет. Под командой я имею в виду исполняемый файл в пути, который я могу запустить из командной строки ( ls , grep , sed и т. Д.).

Я не пытаюсь разработать пакет из команды, что можно сделать с помощью:

dpkg -S `which command`

Я хочу наоборот, список команд из пакета.

12
задан 19 March 2014 в 14:35

4 ответа

Следующий небольшой цикл обработает это с установленными пакетами.

$ for f in $(dpkg -L login); do [[ $(type -P "${f##*/}") == "$f" ]] && echo ${f##*/}; done
nologin
lastlog
newgrp
faillog
su
login
sg

Как это работает:

  • dpkg -L package генерирует список всех файлов в пакете, которого мы выполняем итерации через.
  • Мы снимаем изоляцию с имени каталога с небольшим bashism: ${f##*/} и
  • Используя встроенное ударом type -P command мы видим, ли та команда и в пути и что его путь равняется файлу, с которого мы запустили.
  • Мы заканчиваем путем откачки сокращенной команды.
  • [[ condition ]] && command просто сокращение удара от если.. затем оператор.

Важно отметить, что не все пакеты содержат команды, к которым Вы ожидали бы их. Apache разделяется по нескольким пакетам (с -common и -bin подпакеты) и vlc команда не находится в vlc пакет, это находится в vlc-nox. Существует много примеров как этот.


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

for f in $(dpkg -L login); do [[ $f =~ ^${PATH//:/|} ]] && echo ${f##*/}; done

Существенное различие здесь [[$f =~ ^${PATH//:/|} ]]. Это - поиск regex в Bash. ${PATH//:/|} часть берет содержание $PATH и взламывает их грязный небольшой regex. Условие должно проверить, что строка начинается с части пути.

8
ответ дан 16 November 2019 в 14:32

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

export PACKAGE="login"; source /etc/lsb-release; source <(dpkg-architecture); for f in $(wget -qO- "http://packages.ubuntu.com/$DISTRIB_CODENAME/$DEB_BUILD_ARCH/$PACKAGE/filelist" | sed -n '1,/<pre>/d;/<\/pre>/,$d;p'); do [[ $f =~ ^${PATH//:/|} ]] && echo ${f##*/}; done

, Это ужасающе более сложно, таким образом, я запишу сломанную версию:

export PACKAGE="login";
source /etc/lsb-release;
source <(dpkg-architecture);

URL="http://packages.ubuntu.com/$DISTRIB_CODENAME/$DEB_BUILD_ARCH/$PACKAGE/filelist"

# We grab the packages.ubuntu.com version of the file list (and strip it with sed)
for f in $(wget -qO- "$URL" | sed -n '1,/<pre>/d;/<\/pre>/,$d;p'); do

    # We then compare every file provided in the package with every path stub
    [[ $f =~ ^${PATH//:/|} ]] && echo ${f##*/};
done
1
ответ дан 16 November 2019 в 14:32

Более легкий метод просто запрашивает сеть:

release=$(lsb_release -sc)
arch=$(uname -m)
package=$@

for i in $package; do
   printf "List of files in $i package"
   curl http://packages.ubuntu.com/$release/$arch/$i/filelist 2>/dev/null | grep -oP '/[\w\d/.]+$
done

Это имеет преимущество, что Вы только должны были бы завихриться и sed (что система Ubuntu не имеет ими), и можно изменить его с wget легко при необходимости. Это запрашивает несколько пакетов с единственной командой, которая является плюс.

<час>

Любой эквивалент с другим языком программирования + синтаксический анализатор HTML должен работать лучше и менее вероятно повреждаться, если что-то изменяется в списке пакета.

Изменение хоста можно также запросить базу данных Debian.

0
ответ дан 16 November 2019 в 14:32

Перечислите файлы в пакете, которые находятся в каталоге в ПУТИ. Только необходимо рассмотреть ПУТЬ по умолчанию, не любые пользовательские настройки, так как пакеты только используют стандартные каталоги.

dpkg -L PACKAGE-NAME… | sed -n 's!^\(/s\?bin\|/usr/s\?bin\|/usr/games\)/!!p' | sort

Удалите s\? части, если Вы только хотите программы, предназначенные для обычных пользователей без sudo.

Если пакет не установлен, замена dpkg -L apt-file -F list.

Это пропускает несколько программ, потому что им предоставляют через альтернативы. Например, для ftp пакет, только netkit-ftp и pftp обеспечиваются, но этот пакет на самом деле обеспечивает ftp команда, потому что /usr/bin/ftp символьная ссылка на /etc/alternatives/ftp который является символьной ссылкой на один из ftp реализации в системе, потенциально /usr/bin/netkit-ftp. Следующая команда (который не является примером хорошего программирования, просто большая острота) перечисляет команды, обеспеченные пакетом с помощью механизма альтернатив, как в настоящее время настроено.

perl -lwe 'foreach (`dpkg -L @ARGV`) {chomp; ++$p{$_}} foreach (</bin/* /sbin/* /usr/bin/* /usr/sbin/*>) {$e = readlink; next unless defined $e and $e =~ m!^/etc/alternatives/!; $t = readlink $e; print if $p{$t}}' PACKAGE_NAME…

Если Вы хотите перечислить команды, которые могли бы быть обеспечены через альтернативу, которая в настоящее время настраивается для указания на другой пакет, необходимо проанализировать файлы в /var/lib/dpkg/alternatives.

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

3
ответ дан 23 November 2019 в 03:41

Другие вопросы по тегам:

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