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
これはcertbot、config-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 スクリプトからプログラムが存在するかどうかを確認するにはどうすればよいですか?
こちらもご覧ください