Проверьте, установлен ли пакет apt-get, а затем установите его, если он не в Linux?
Я работаю над системой Ubuntu, и в настоящее время это то, что я делаю:
if ! which command > /dev/null; then
echo -e "Command not found! Install? (y/n) \c"
read
if "$REPLY" = "y"; then
sudo apt-get install command
fi
fi
Это то, что большинство людей будет делать? Или есть более элегантное решение?
Ответы
Ответ 1
Чтобы проверить, установлен ли packagename
, введите:
dpkg -s <packagename>
Вы также можете использовать dpkg-query
, который имеет более аккуратный вывод для вашей цели, и принимает также дикие карты.
dpkg-query -l <packagename>
Чтобы узнать, какой пакет принадлежит command
, попробуйте:
dpkg -S `which <command>`
Для получения дополнительной информации см. статью Узнайте, установлен ли пакет в Linux и dpkg cheat sheet.
Ответ 2
Чтобы быть немного более явным, вот немного bash script, который проверяет наличие пакета и устанавливает его, если требуется. Конечно, вы можете сделать другие вещи, обнаружив, что пакет отсутствует, например, просто выходить с кодом ошибки.
PKG_OK=$(dpkg-query -W --showformat='${Status}\n' the.package.name|grep "install ok installed")
echo Checking for somelib: $PKG_OK
if [ "" == "$PKG_OK" ]; then
echo "No somelib. Setting up somelib."
sudo apt-get --force-yes --yes install the.package.name
fi
Если script работает внутри графического интерфейса (например, это Nautilus script), вы, вероятно, захотите заменить вызов 'sudo' на "gksudo".
Ответ 3
Этот однострочный файл возвращает 1 (установлен) или 0 (не установлен) для пакета nano.
$(dpkg-query -W -f='${Status}' nano 2>/dev/null | grep -c "ok installed")
даже если пакет не существует/недоступен.
В приведенном ниже примере устанавливается пакет nano, если он не установлен.
if [ $(dpkg-query -W -f='${Status}' nano 2>/dev/null | grep -c "ok installed") -eq 0 ];
then
apt-get install nano;
fi
Ответ 4
Я предлагаю это обновление, так как Ubuntu добавил свой "Архив личных пакетов" (PPA), как только на этот вопрос был дан ответ, и пакеты PPA имеют другой результат.
-
Собственный пакет репозитория Debian не установлен:
~$ dpkg-query -l apache-perl
~$ echo $?
1
-
Пакет PPA зарегистрирован на хосте и установлен:
~$ dpkg-query -l libreoffice
~$ echo $?
0
-
Пакет PPA зарегистрирован на хосте, но не установлен:
~$ dpkg-query -l domy-ce
~$ echo $?
0
~$ sudo apt-get remove domy-ce
[sudo] password for user:
Reading package lists... Done
Building dependency tree
Reading state information... Done
Package domy-ce is not installed, so not removed
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
Также размещено по адресу: https://superuser.com/questions/427318/test-if-a-package-is-installed-in-apt/427898
Ответ 5
dpkg -s
программное использование
Мне нравится dpkg -s
как он выходит со статусом 1
если какой-либо из пакетов не установлен, что упрощает его автоматизацию:
pkgs='qemu-user pandoc'
if ! dpkg -s $pkgs >/dev/null 2>&1; then
sudo apt-get install $pkgs
fi
man dpkg
сожалению, man dpkg
не документирует статус выхода, но я думаю, что на него можно полагаться в достаточной безопасности:
-s, --status package-name...
Report status of specified package.
Смотрите также:
Проверено на Ubuntu 18.10.
Ответ 6
Это, похоже, работает очень хорошо.
$ sudo dpkg-query -l | grep <some_package_name> | wc -l
- Он либо возвращает
0
, если не установлен, либо некоторое число > 0
, если установлено.
Ответ 7
UpAndAdam писал (а):
Однако вы не можете просто полагаться на коды возврата здесь для сценариев
В моем опыте вы можете полагаться на коды выхода dkpg.
Код возврата dpkg -s 0, если пакет установлен и 1, если это не так, поэтому самым простым решением я нашел:
dpkg -s <pkg-name> 2>/dev/null >/dev/null || sudo apt-get -y install <pkg-name>
Прекрасно работает для меня...
Ответ 8
Я нашел, что все вышеперечисленные решения могут привести к ложному срабатыванию, если пакет установлен, а затем удален, но пакет установки остается в системе.
Повторить:
Установить пакет apt-get install curl
Удалить пакет apt-get remove curl
Теперь проверьте выше ответы.
Кажется, что следующая команда разрешает это условие:
dpkg-query -W -f='${Status}\n' curl | head -n1 | awk '{print $3;}' | grep -q '^installed$'
Это приведет к окончательному
установлен или не установлен
Ответ 9
Я остановился на одном из ответов Нулти:
MISSING=$(dpkg --get-selections $PACKAGES 2>&1 | grep -v 'install$' | awk '{ print $6 }')
# Optional check here to skip bothering with apt-get if $MISSING is empty
sudo apt-get install $MISSING
По сути, сообщение об ошибке из dpkg --get-selections
гораздо проще проанализировать, чем большинство других, потому что оно не включает такие состояния, как "deinstall". Он также может проверять несколько пакетов одновременно, чего нельзя сделать только с помощью кодов ошибок.
Объяснение/пример:
$ dpkg --get-selections python3-venv python3-dev screen build-essential jq
dpkg: no packages found matching python3-venv
dpkg: no packages found matching python3-dev
screen install
build-essential install
dpkg: no packages found matching jq
Поэтому grep удаляет установленные пакеты из списка, а awk извлекает имена пакетов из сообщения об ошибке, в результате чего MISSING='python3-venv python3-dev jq'
, который можно просто вставить в команду установки.
Я не слепо выдаю apt-get install $PACKAGES
потому что, как упоминалось в комментариях, это может неожиданно обновить пакеты, которые вы не планировали; не очень хорошая идея для автоматизированных процессов, которые, как ожидается, будут стабильными.
Ответ 10
$name="rsync"
[ `which $name` ] $$ echo "$name : installed" || sudo apt-get install -y $name
Ответ 11
Это сделает это. apt-get install
является идемпотентным.
sudo apt-get install command
Ответ 12
Использование:
apt-cache policy <package_name>
Если он не установлен, он покажет:
Installed: none
В противном случае он покажет:
Installed: version
Ответ 13
Эта функция уже существует в Ubuntu и Debian в пакете command-not-found
.
Ответ 14
which <command>
if [ $? == 1 ]; then
<pkg-manager> -y install <command>
fi
Ответ 15
apt list [packagename]
кажется самым простым способом сделать это за пределами dpkg и более старых apt- * tools
Ответ 16
Для Ubuntu apt предоставляет достаточно приличный способ сделать это. Ниже приведен пример для Google Chrome:
apt -qq list google-chrome-stable 2>/dev/null | grep -qE "(installed|upgradeable)" || apt-get install google-chrome-stable
Я перенаправляю вывод ошибок на ноль, потому что apt предупреждает против использования своего "нестабильного кли". Я подозреваю, что список пакетов стабилен, поэтому я думаю, что можно выбросить это предупреждение. -qq делает супер тихий.
Ответ 17
У меня было подобное требование при запуске теста локально, а не в докере. По сути, я хотел установить только те файлы .deb, которые не были установлены.
# If there are .deb files in the folder, then install them
if [ 'ls -1 *.deb 2> /dev/null | wc -l' -gt 0 ]; then
for file in *.deb; do
# Only install if not already installed (non-zero exit code)
dpkg -I ${file} | grep Package: | sed -r 's/ Package:\s+(.*)/\1/g' | xargs dpkg -s
if [ $? != 0 ]; then
dpkg -i ${file}
fi;
done;
else
err "No .deb files found in '$PWD'"
fi
Я думаю, что единственная проблема, которую я вижу, заключается в том, что он не проверяет номер версии пакета, поэтому, если файл .deb является более новой версией, это не перезапишет установленный в данный момент пакет.
Ответ 18
Эта команда является наиболее запоминающейся:
dpkg --get-selections <package-name>
Если он установлен, он печатает:
< имя-пакетa > установить
В противном случае он печатает
Не найдено пакетов, соответствующих имени < package-name > .
Это было протестировано на Ubuntu 12.04.1 (Precise Pangolin).
Ответ 19
Многое было сказано, но для меня самый простой способ это:
dpkg -l | grep packagename
Ответ 20
В Баш:
PKG="emacs"
dpkg-query -l $PKG > /dev/null || sudo apt install $PKG
Обратите внимание, что в PKG может быть строка с несколькими пакетами.
Ответ 21
Я использую следующий способ:
which mySQL 2>&1|tee 1> /dev/null
if [[ "$?" == 0 ]]; then
echo -e "\e[42m MySQL already installed. Moving on...\e[0m"
else
sudo apt-get install -y mysql-server
if [[ "$?" == 0 ]]; then
echo -e "\e[42mMy SQL installed\e[0m"
else
echo -e "\e[42Installation failed\e[0m"
fi
fi
Ответ 22
Кажется, что в настоящее время у apt-get
есть опция --no-upgrade
которая просто делает то, что хочет OP:
--no-upgrade
Не обновлять пакеты. При использовании вместе с установкой no-upgrade не позволит обновить перечисленные пакеты, если они уже установлены.
Manpage от https://linux.die.net/man/8/apt-get
Поэтому вы можете использовать
apt-get install --no-upgrade package
и package
будет установлен только если его нет.