Check if a package is installed and then install it if it's not

匿名 (未验证) 提交于 2019-12-03 02:22:01

问题:

I'm working on a Ubuntu system and currently this is what I'm doing:

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

Is this what most people would do? Or is there a more elegant solution?

回答1:

To check if packagename was installed, type:

dpkg -s 

You can also use dpkg-query that has a neater output for your purpose, and accepts wild cards, too.

dpkg-query -l 

To find what package owns the command, try:

dpkg -S `which `

For further details, see article Find out if package is installed in Linux and dpkg cheat sheet.



回答2:

To be a little more explicit, here's a bit of bash script that checks for a package and installs it if required. Of course, you can do other things upon finding that the package is missing, such as simply exiting with an error code.

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

If the script runs within a GUI (e.g. it is a Nautilus script), you'll probably want to replace the 'sudo' invocation with a 'gksudo' one.



回答3:

This one-liner returns 1 (installed) or 0 (not installed) for the 'nano' package..

$(dpkg-query -W -f='${Status}' nano 2>/dev/null | grep -c "ok installed")

even if the package does not exist / is not available.

The example below installs the 'nano' package if it is not installed..

if [ $(dpkg-query -W -f='${Status}' nano 2>/dev/null | grep -c "ok installed") -eq 0 ]; then   apt-get install nano; fi


回答4:

I offer this update since Ubuntu added its "Personal Package Archive" (PPA) just as this question was answered, and PPA packages have a different result.

  1. Native Debian repository package not installed:

    ~$ dpkg-query -l apache-perl ~$ echo $? 1
  2. PPA package registered on host and installed:

    ~$ dpkg-query -l libreoffice ~$ echo $? 0
  3. PPA package registered on host but not installed:

    ~$ 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.

Also posted on: https://superuser.com/questions/427318/test-if-a-package-is-installed-in-apt/427898



回答5:

UpAndAdam wrote:

However you can't simply rely on return codes here for scripting

In my experience you can rely on dkpg's exit codes.

The return code of dpkg -s is 0 if the package is installed and 1 if it's not, so the simplest solution I found was:

dpkg -s  2>/dev/null >/dev/null || sudo apt-get -y install 

Works fine for me...



回答6:

This seems to work pretty well.

$ sudo dpkg-query -l | grep  | wc -l
  • It either returns 0 if not installed or some number > 0 if installed.


回答7:

I've found all solutions above can produce a false positive if a package is installed and then removed yet the installation package remains on the system.

To replicate: Install package apt-get install curl
Remove package apt-get remove curl

Now test above answers.

The following command seems to solve this condition:
dpkg-query -W -f='${Status}\n' curl | head -n1 | awk '{print $3;}' | grep -q '^installed$'

This will result in a definitive installed or not-installed



回答8:

$name="rsync"  [ `which $name` ] $$ echo "$name : installed" || sudo apt-get install -y $name


回答9:

This will do it. apt-get install is idempotent.

sudo apt-get install command


回答10:

This feature already exists in Ubuntu and Debian, in the command-not-found package.



回答11:

Use:

apt-cache policy 

If it is not installed, it will show:

Installed: none

Otherwise it will show:

Installed: version


回答12:

apt list [packagename]

seems to be the simplest way to do it outside of dpkg and older apt-* tools



回答13:

which  if [ $? == 1 ]; then      -y install  fi


回答14:

This command is the most memorable:

dpkg --get-selections 

If it's installed it prints:

install

Otherwise it prints

No packages found matching .

This was tested on Ubuntu 12.04.1 (Precise Pangolin).



回答15:

For Ubuntu, apt provides a fairly decent way to do this. Below is an example for google chrome:

if apt -qq list google-chrome-stable 2>/dev/null | grep -q installed ; then   apt-get install google-chrome-stable fi

I'm redirecting error output to null because apt warns against using its "unstable cli". I suspect list package is stable so I think it's ok to throw this warning away. The -qq makes apt super quiet.



回答16:

I've settled on one based on Nultyi's answer:

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

Basically, the error message from dpkg --get-selections is far easier to parse than most of the others, because it doesn't include statuses like "deinstall". It also can check multiple packages simultaneously, something you can't do with just error codes.

Explanation/example:

$ 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

So grep removes installed packages from the list, and awk pulls the package names out from the error message, resulting in MISSING='python3-venv python3-dev jq', which can be trivially inserted into an install command.

I'm not blindly issuing an apt-get install $PACKAGES because as mentioned in the comments, this can unexpectedly upgrade packages you weren't planning on; not really a good idea for automated processes that are expected to be stable.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!