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


10

パッケージがインストールされているかどうかをテスト/レポートするシェルスクリプトメソッドが必要です。詳細は必要ありません。論理フローを設定するためのブール値の戻りのみです。私が見たパッケージがインストールされている場合は、検索が、dpkg戻って複雑な出力とそのフォーマットの変更は、パッケージがDebianのリポジトリ内またはUbuntuのPPAにあるかどうかによって異なります。

私はそれapt-cacheがかなり良い仕事をするのを見つけて、私はこの方法を思いつきました:

is_installed=0
test_installed=( `apt-cache policy package-name | grep "Installed:" ` )
[ ! "${test_installed[1]}" == "(none)" ] && is_installed=1

誰かがもっと簡単な、またはもっと直接的な方法を知っていますか?

回答:


12

dpkg-query リンクされた投稿のように、そのようなスクリプトのコンテキストでAPTシステムに直接バインドするために、たとえば利用可能なPythonライブラリを使用することを除いて、仕事に最も適したツールのようです。

dpkg-query

dpkg-query -Wf'${db:Status-abbrev}' package-name 2>/dev/null | grep -q '^i'

0パッケージがインストールされている場合はtrue(シェルスクリプトの終了ステータス)を返し、1そうでない場合はfalse(終了ステータス)を返します。

  • -W「表示」を意味します(dpkg-query要求されたアクションが必要です)。
  • -f 出力の形式を変更します。
  • db:Status-abbrev パッケージステータスの短縮形です。
  • 2>/dev/nulldpkg-query無効なパッケージ名が指定された場合は無音になります。これをどのように処理すべきかは、ケース・ツー・ケースの問題である可能性があります。
  • grep -q 一致する場合はtrue、それ以外の場合はfalseを返します。

頻繁に使用する場合は、単純な関数にすることができます。

#!/bin/sh
debInst() {
    dpkg-query -Wf'${db:Status-abbrev}' "$1" 2>/dev/null | grep -q '^i'
}

if debInst "$1"; then
    printf 'Why yes, the package %s _is_ installed!\n' "$1"
else
    printf 'I regret to inform you that the package %s is not currently installed.\n' "$1"
fi

または単に

#!/bin/sh
if dpkg-query -Wf'${db:Status-abbrev}' "$1" 2>/dev/null | grep -q '^i'; then
    printf 'Why yes, the package "%s" _is_ installed!\n' "$1"
else
    printf 'I regret to inform you that the package "%s" is not currently installed.\n' "$1"
fi

これは間違いなく正しいですdpkg-query -l "$package" | grep -q ^.iが、通常はそれで十分です(覚えやすい)。
12

1
@phogg:はい、スクリプトで実行することになっているかどうかによって異なります。また、dpkg-query -l出力は単なるユーザープレゼンテーションモードであるため、出力は適切に設定されていません。そのため、プレゼンテーションが変更されると、そのようなスクリプトが壊れる可能性があります。
ダニエルアンダーソン、2012年

@ダニエル。戻りコードによるアプローチが好きです。コード内の詳細で私の答えをご覧ください。
tahoar

10.04では、フォーマットオプションdb:Status-abbrevは存在しないようですdpkg-query -Wf'${Version}' ${pkg} 2>/dev/null | grep -q '^\d*'
scottynomad

1

ダニエルの提案を次の3つのパッケージでテストしました。

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

    ~$ dpkg-query -Wf'${db:Status-abbrev}' apache-perl
    ~$ echo $?
    1
    
  2. ホストに登録され、インストールされているPPAパッケージ:

    ~$ dpkg-query -Wf'${db:Status-abbrev}' libreoffice
    ~$ echo $?
    0
    
  3. ホストに登録されているがインストールされていないPPAパッケージ:

    ~$ dpkg-query -Wf'${db:Status-abbrev}' 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.
    

私はこのアプローチを気に入っていますが、PPAパッケージでの戻りコードは信頼できないようです。それまでは、apt-cache policyコマンドの戻りの解析に固執すると思います。


さて、あなたのコード例はあなたがすべきだと私が言ったものではありませんが、あなたgrepはあなたの貼り付けの一部を逃しただけだと思います。問題を実際に再現することはできませんが、コード例が現在不完全である可能性があるため、修正してください。DebianまたはUbuntuを実行していますか?
ダニエルアンダーソン

私はUbuntu 10.04を実行しています(PPAはまっすぐなDebianをサポートしていませんか?)。1)dkpg-queryコマンドがstdoutに何も書き込まず、grepが常に戻りコードをスローするため、私のコードはあなたのgrepをドロップしました。インストールされている場合、dpkg-queryリターンコードは0です。
-tahoar

2
1.投稿に「Debian」のタグを付けないでください。2. grepコマンドで演じられた部分を理解していないと思いますので、それを取り除き、機能しないと言いましたか?一致しない場合、つまりプログラムがインストールされていないか利用できない場合、またはプログラムがインストールされている場合は、grep -q戻りコードを返します。私の投稿でそれを説明しました。10
Daniel Andersson、2012年

1
#!/bin/bash

# Check for dependencies 
check_deps () {
DEPS=$(echo {dialog,sqlite3,openssh-client})
for i in $DEPS ; do
    dpkg-query -W -f='${Package}\n' | grep ^$i$ > /dev/null
    if [ $? != 0 ] ; then
        echo "Installing deps ..."
        aptitude install $i -y > /dev/null
    fi
done  
}

# execute the check_deps function
check_deps

-1、問題は依存関係チェックに関するものではありません。また、コマンドの各部分が何をしているかを説明します。そうしないと、他の人は何が起こっているのかを見ることができません。
Daniel Andersson、

DEPS=$(echo {dialog,sqlite3,openssh-client})と同等に書くことができますDEPS="dialog sqlite3 openssh-client"
Daniel Andersson、

1

ダニエル・アンダーソンの答えは好きですが、うまくいきませんでした。私はUbuntu 12.04を使用しています。

dpkgのmanページから、dpkgdb:Status-abbrev 1.16.2以降でのみ機能します。

          db:Status-Abbrev
                 It  contains the abbreviated package status, such as “ii”
                 (since dpkg 1.16.2).

私の解決策は、Statusフォーマッタだけでレガシー動作を使用することでした:

dpkg-query -Wf'${Status}' {my_pkg_name}

出力

install ok installed 

これが他の表現における「ii」のインスピレーションだったと思います。

したがって、Daniel Anderssonの回答を完全に適合させて、古いバージョンのdpkg、つまり古いUbuntuディストリビューションで作業するには:

dpkg-query -Wf'${Status}' {your_pkg_name} 2>/dev/null | grep -q "install ok installed"

戻り値:

  • 0-パッケージがインストールされている、または
  • 1-パッケージがインストールされていません。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.