На этот вопрос уже есть ответ здесь:
Я Любопытно, какие команды в моей системе предоставляет определенный пакет. Под командой я имею в виду исполняемый файл в пути, который я могу запустить из командной строки ( ls
, grep
, sed
и т. Д.).
Я не пытаюсь разработать пакет из команды, что можно сделать с помощью:
dpkg -S `which command`
Я хочу наоборот, список команд из пакета.
Следующий небольшой цикл обработает это с установленными пакетами.
$ for f in $(dpkg -L login); do [[ $(type -P "${f##*/}") == "$f" ]] && echo ${f##*/}; done
nologin
lastlog
newgrp
faillog
su
login
sg
Как это работает:
dpkg -L package
генерирует список всех файлов в пакете, которого мы выполняем итерации через.${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. Условие должно проверить, что строка начинается с части пути.
Мой другой ответ является почти бесспорным, но только работает на установленные пакеты. Вот трещина в версии, которая работает на пакеты, еще не установленные (но, которые только доступны в основных репозиториях)
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
Более легкий метод просто запрашивает сеть:
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.
Перечислите файлы в пакете, которые находятся в каталоге в ПУТИ. Только необходимо рассмотреть ПУТЬ по умолчанию, не любые пользовательские настройки, так как пакеты только используют стандартные каталоги.
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
, который мешает (и на самом деле технически невозможный, если сценарий установки пакета не следует конвенциям) запрашивать альтернативы, обеспеченные удаленным пакетом.