266

私は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

これはほとんどの人がすることでしょうか?または、よりエレガントなソリューションはありますか?

4

25 に答える 25

351

packagenameがインストールされているかどうかを確認するには、次のように入力します。

dpkg -s <packagename>

dpkg-query目的に合わせてより適切な出力があり、ワイルドカードも受け入れる を使用することもできます。

dpkg-query -l <packagename>

を所有しているパッケージを見つけるにはcommand、次を試してください。

dpkg -S `which <command>`

詳細については、記事Linux にパッケージがインストールされているかどうかを確認するおよびdpkg チート シートを参照してください。

于 2009-08-19T06:27:47.443 に答える
108

もう少し明確にするために、パッケージをチェックして必要に応じてインストールする Bash スクリプトを次に示します。もちろん、パッケージが見つからない場合は、単にエラー コードで終了するなど、他のことを行うことができます。

REQUIRED_PKG="some-package"
PKG_OK=$(dpkg-query -W --showformat='${Status}\n' $REQUIRED_PKG|grep "install ok installed")
echo Checking for $REQUIRED_PKG: $PKG_OK
if [ "" = "$PKG_OK" ]; then
  echo "No $REQUIRED_PKG. Setting up $REQUIRED_PKG."
  sudo apt-get --yes install $REQUIRED_PKG
fi

スクリプトが GUI 内で実行される場合 ( Nautilusスクリプトなど)、おそらく「sudo」呼び出しを「gksudo」呼び出しに置き換えたいと思うでしょう。

于 2012-05-03T20:44:36.947 に答える
90

このワンライナーは、「nano」パッケージに対して 1 (インストール済み) または 0 (インストールされていない) を返します...

$(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
于 2014-03-23T15:22:03.830 に答える
29

dpkg-query --showformat='${db:Status-Status}'

これにより、変更される可能性が低く、決定論的に簡単に比較できる小さな出力文字列が生成されますgrep

pkg=hello
status="$(dpkg-query -W --showformat='${db:Status-Status}' "$pkg" 2>&1)"
if [ ! $? = 0 ] || [ ! "$status" = installed ]; then
  sudo apt install $pkg
fi

以前にパッケージをインストールしたことがなく、 などの特定のパッケージを削除した後に、ステータス 1で終了し、stderr に出力されるため、$? = 0チェックが必要です。hellodpkg-query

dpkg-query: no packages found matching hello

を出力する代わりにnot-installed。は2>&1、端末への送信を妨げている場合にも、そのエラー メッセージをキャプチャします。

複数のパッケージの場合:

pkgs='hello certbot'
install=false
for pkg in $pkgs; do
  status="$(dpkg-query -W --showformat='${db:Status-Status}' "$pkg" 2>&1)"
  if [ ! $? = 0 ] || [ ! "$status" = installed ]; then
    install=true
    break
  fi
done
if "$install"; then
  sudo apt install $pkgs
fi

可能なステータスは、次のように文書化されman dpkg-queryています。

   n = Not-installed
   c = Config-files
   H = Half-installed
   U = Unpacked
   F = Half-configured
   W = Triggers-awaiting
   t = Triggers-pending
   i = Installed

1 文字バージョンは で取得できますがdb:Status-Abbrev、アクションとエラー ステータスが一緒に表示されるため、3 文字になり、それをカットする必要があります。

Config-filesしたがって、代わりに大文字のないステータス ( vs config-files) が変化しないことに頼るのに十分信頼できると思います。

dpkg -s終了ステータス

残念ながら、これはほとんどのユーザーが望むことを行いません:

pkgs='qemu-user pandoc'
if ! dpkg -s $pkgs >/dev/null 2>&1; then
  sudo apt-get install $pkgs
fi

一部のパッケージでは、たとえばcertbot、次のことを行うためです。

sudo apt install certbot
sudo apt remove certbot

これはcertbotconfig-files構成ファイルがマシンに残っていることを意味します。そして、その状態でdpkg -sも を返します0。これは、パッケージのメタデータがまだ保持されているため、これらの構成ファイルをより適切に処理できるためです。

実際にdpkg -sreturn 1 を必要に応じて作成するには、次の--purgeようにする必要があります。

sudo apt remove --purge certbot

実際にnot-installed/に移動しdpkg-query: no packages found matchingます。

特定のパッケージのみが構成ファイルを残すことに注意してください。のような単純なパッケージは、 fromなしでhello直接installed移動します。not-installed--purge

Ubuntu 20.10 でテスト済み。

Pythonaptパッケージ

aptPython apt インターフェイスを公開する、Ubuntu 18.04と呼ばれるプリインストールされた Python 3 パッケージがあります。

パッケージがインストールされているかどうかを確認し、インストールされていない場合はインストールするスクリプトは、次の場所にあります: How to install a package using the python-apt API

参照用のコピーを次に示します。

#!/usr/bin/env python
# aptinstall.py

import apt
import sys

pkg_name = "libjs-yui-doc"

cache = apt.cache.Cache()
cache.update()
cache.open()

pkg = cache[pkg_name]
if pkg.is_installed:
    print "{pkg_name} already installed".format(pkg_name=pkg_name)
else:
    pkg.mark_install()

    try:
        cache.commit()
    except Exception, arg:
        print >> sys.stderr, "Sorry, package installation failed [{err}]".format(err=str(arg))

PATH代わりに実行可能ファイルがあるかどうかを確認します

参照: Bash スクリプトからプログラムが存在するかどうかを確認するにはどうすればよいですか?

こちらもご覧ください

于 2019-01-17T15:49:17.073 に答える
12

Ubuntu は「Personal Package Archive」(PPA) を追加しましたが、PPA パッケージの結果は異なります。

  1. ネイティブのDebianリポジトリ パッケージがインストールされていません:

    ~$ dpkg-query -l apache-perl
    ~$ echo $?
    1
    
  2. ホストに登録され、インストールされた PPA パッケージ:

    ~$ dpkg-query -l libreoffice
    ~$ echo $?
    0
    
  3. ホストに登録されているがインストールされていない 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.
    

関連記事:パッケージが APT にインストールされているかどうかをテストする

于 2012-05-23T13:12:11.643 に答える
6

これはかなりうまくいくようです。

$ sudo dpkg-query -l | grep <some_package_name> | wc -l
  • インストールされていない場合は返さ0れるか、インストールされている場合は何らかの番号が返さ> 0れます。
于 2013-08-20T17:52:47.813 に答える
4

パッケージがインストールされてから削除された場合、以前の回答のすべてのソリューションが誤検知を引き起こす可能性があることを発見しましたが、インストールパッケージはシステムに残ります。

複製するには:

パッケージのインストール パッケージapt-get install curl
の削除apt-get remove curl

ここで、以前の回答をテストします。

次のコマンドは、この状態を解決するようです。

dpkg-query -W -f='${Status}\n' curl | head -n1 | awk '{print $3;}' | grep -q '^installed$'

これにより、インストール済みまたはインストールの決定的な結果が得られます。

于 2016-05-03T14:48:00.187 に答える
3
$name="rsync"

[ `which $name` ] $$ echo "$name : installed" || sudo apt-get install -y $name
于 2015-09-11T14:58:08.547 に答える
1

command-not-foundこの機能は、パッケージのUbuntuとDebianにすでに存在します。

于 2009-08-19T09:15:52.567 に答える
0

もう少し「エレガント」に基づいたものです。退屈だから。

#!/bin/bash
FOUND=("\033[38;5;10m")
NOTFOUND=("\033[38;5;9m")
PKG="${@:1}"
command ${PKG} &>/dev/null
if [[ $? != 0 ]]; then
    echo -e "${NOTFOUND}[!] ${PKG} not found [!]"
    echo -e "${NOTFOUND}[!] Would you like to install ${PKG} now ? [!]"
    read -p "[Y/N] >$ " ANSWER
    if [[ ${ANSWER} == [yY] || ${ANSWER} == [yY][eE][sS] ]]; then
        if grep -q "bian" /etc/os-release; then
            sudo apt-get install ${PKG}
        elif grep -q "arch" /etc/os-release; then
            if [[ -f /bin/yay ]] || [[ -f /bin/yaourt ]]; then
                yaourt -S ${PKG} 2>./err || yay -S ${PKG} 2>./err
            else
                sudo pacman -S ${PKG}
            fi
        elif grep -q "fedora" /etc/os-release; then
             sudo dnf install ${PKG}
        else
            echo -e "${NOTFOUND}[!] This script couldn't detect your package manager [!]"
            echo -e "${NOTFOUND}[!] Manually install it [!]"
        fi
    elif [[ ${ANSWER} == [nN] || ${ANSWER} == [nN][oO] ]]; then
        echo -e "${NOTFOUND}[!] Exiting [!]"
    fi
else
    echo -e "${FOUND}[+] ${PKG} found [+]"
fi
于 2021-12-14T02:10:58.637 に答える
0

次の行に沿って何かを使用することを提案する回答:

dpkg-query --showformat '${db:Status-Status}\n' --show $package | grep -q '^installed$'
dpkg-query --showformat '${Status}\n' --show $package | grep -q '^install ok installed$'

は正しい。

ただし、パッケージがインストールされていてdpkg-dev、パッケージがインストールされているかどうかを確認するだけでなく、次のことも行う場合:

  • パッケージが特定のバージョンにインストールされているかどうかを知りたい
  • 特定のアーキテクチャでパッケージを持ちたい
  • 仮想パッケージが提供されているかどうかを確認したい

dpkg-checkbuilddeps次に、このジョブのツールを悪用できます。

dpkg-checkbuilddeps -d apt /dev/null

これにより、apt がインストールされているかどうかがチェックされます。

以下は、apt が少なくともバージョン 2.3.15 にインストールされているかどうか、grep が amd64 としてインストールされているかどうか、仮想パッケージx-window-managerがインストールされたパッケージの一部によって提供されているかどうかを確認します。

dpkg-checkbuilddeps -d 'apt (>= 2.3.15), grep:amd64, x-window-manager' /dev/null

dpkg-checkbuilddeps の終了ステータスは、依存関係が満たされているかどうかをスクリプトに伝えます。このメソッドは複数のパッケージを渡すことをサポートしているため、複数のdpkg-checkbuilddepsパッケージがインストールされているかどうかを確認したい場合でも、1 回実行するだけで済みます。

于 2022-02-15T09:51:49.783 に答える