检查是否安装了包,如果没有安装,则安装它。

时间:2022-04-04 23:54:24

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

我正在开发一个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

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

这是大多数人都会做的吗?还是有更优雅的解决方案?

16 个解决方案

#1


265  

To check if packagename was installed, type:

要检查packagename是否已安装,请键入:

dpkg -s <packagename>

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

您还可以使用具有neater输出的dpkg查询,并接受通配符。

dpkg-query -l <packagename>

To find what package owns the command, try:

要找到什么包拥有该命令,请尝试:

dpkg -S `which <command>`

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

有关进一步的详细信息,请参阅文章了解在Linux和dpkg备件中是否安装了包。

#2


59  

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.

为了更明确一点,这里有一个bash脚本,它检查包并在需要时安装它。当然,您可以在发现包丢失的情况下进行其他操作,比如简单地使用错误代码退出。

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.

如果脚本在GUI中运行(例如,它是一个Nautilus脚本),您可能希望用“gksudo”替换“sudo”调用。

#3


55  

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

这一行返回1(已安装)或0(未安装)用于“nano”包。

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

下面的示例安装“nano”包,如果它没有安装。

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

#4


11  

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.

我提供这个更新,因为Ubuntu添加了它的“个人包归档”(PPA),就像这个问题被回答一样,而PPA包也有不同的结果。

  1. Native Debian repository package not installed:

    未安装的本地Debian存储库包:

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

    在主机上注册的PPA包:

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

    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.
    

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

还贴在:https://superuser.com/questions/427318/test-if-a-package-is-installed-in-apt/427898

#5


7  

UpAndAdam wrote:

UpAndAdam写道:

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

但是,您不能仅仅依靠这里的返回代码来编写脚本。

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

在我的经验中,您可以依赖于dkpg的退出代码。

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的返回码是0,如果不是,那么我找到的最简单的解决方案是:

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

Works fine for me...

对我来说很不错…

#6


4  

This seems to work pretty well.

这似乎很有效。

$ sudo dpkg-query -l | grep <some_package_name> | wc -l
  • It either returns 0 if not installed or some number > 0 if installed.
  • 如果安装了,它将返回0,如果没有安装,则返回0。

#7


3  

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

要复制:安装包的apt-get安装curl移除包的apt-get删除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$'

下面的命令似乎解决这个条件:dpkg-query - w - f = $ {地位} \ n的卷发|头n1 | awk的{打印3美元;} | grep - q ' ^安装美元”

This will result in a definitive installed or not-installed

这将导致最终安装或不安装。

#8


2  

$name="rsync"

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

#9


2  

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

这将做它。apt-get安装是等幂的。

sudo apt-get install command

#10


2  

Use:

使用:

apt-cache policy <package_name>

If it is not installed, it will show:

如果没有安装,它将显示:

Installed: none

Otherwise it will show:

否则它将显示:

Installed: version

#11


1  

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

在Ubuntu和Debian中,这个功能已经存在于命令-not-found包中。

#12


1  

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

我已经解决了一个基于Nultyi的答案:

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.

基本上,来自dpkg的错误消息——get-select比大多数其他的都要容易解析,因为它不包括像“deinstall”这样的状态。它还可以同时检查多个包,这是你不能用错误代码做的事情。

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.

因此,grep从列表中移除已安装的包,awk从错误消息中提取包名,导致丢失='python3-venv python3-dev jq',它可以被trivially插入到安装命令中。

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.

我不是盲目地发布一个apt-get安装包,因为在评论中提到,这可能会出乎意料地升级你没有计划的软件包;对于预期稳定的自动化过程来说,这并不是一个好主意。

#13


0  

apt list [packagename]

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

这似乎是在dpkg和更老的apt工具之外最简单的方法。

#14


0  

which <command>
if [ $? == 1 ]; then
    <pkg-manager> -y install <command>
fi

#15


0  

This command is the most memorable:

这个命令是最令人难忘的:

dpkg --get-selections <package-name>

If it's installed it prints:

如果是安装的,它打印:

<package-name> install

<包名称> 安装

Otherwise it prints

否则它打印

No packages found matching <package-name>.

没有找到匹配的包 <包名> 。

This was tested on Ubuntu 12.04.1 (Precise Pangolin).

这是在Ubuntu 12.04.1(精确穿山甲)上测试的。

#16


0  

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

对于Ubuntu, apt提供了一种相当不错的方法。下面是谷歌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.

我将错误输出重定向到null,因为apt警告不要使用它的“不稳定cli”。我怀疑列表包是稳定的,所以我认为扔掉这个警告是可以的。-qq使apt超级安静。

#1


265  

To check if packagename was installed, type:

要检查packagename是否已安装,请键入:

dpkg -s <packagename>

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

您还可以使用具有neater输出的dpkg查询,并接受通配符。

dpkg-query -l <packagename>

To find what package owns the command, try:

要找到什么包拥有该命令,请尝试:

dpkg -S `which <command>`

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

有关进一步的详细信息,请参阅文章了解在Linux和dpkg备件中是否安装了包。

#2


59  

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.

为了更明确一点,这里有一个bash脚本,它检查包并在需要时安装它。当然,您可以在发现包丢失的情况下进行其他操作,比如简单地使用错误代码退出。

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.

如果脚本在GUI中运行(例如,它是一个Nautilus脚本),您可能希望用“gksudo”替换“sudo”调用。

#3


55  

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

这一行返回1(已安装)或0(未安装)用于“nano”包。

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

下面的示例安装“nano”包,如果它没有安装。

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

#4


11  

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.

我提供这个更新,因为Ubuntu添加了它的“个人包归档”(PPA),就像这个问题被回答一样,而PPA包也有不同的结果。

  1. Native Debian repository package not installed:

    未安装的本地Debian存储库包:

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

    在主机上注册的PPA包:

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

    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.
    

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

还贴在:https://superuser.com/questions/427318/test-if-a-package-is-installed-in-apt/427898

#5


7  

UpAndAdam wrote:

UpAndAdam写道:

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

但是,您不能仅仅依靠这里的返回代码来编写脚本。

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

在我的经验中,您可以依赖于dkpg的退出代码。

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的返回码是0,如果不是,那么我找到的最简单的解决方案是:

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

Works fine for me...

对我来说很不错…

#6


4  

This seems to work pretty well.

这似乎很有效。

$ sudo dpkg-query -l | grep <some_package_name> | wc -l
  • It either returns 0 if not installed or some number > 0 if installed.
  • 如果安装了,它将返回0,如果没有安装,则返回0。

#7


3  

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

要复制:安装包的apt-get安装curl移除包的apt-get删除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$'

下面的命令似乎解决这个条件:dpkg-query - w - f = $ {地位} \ n的卷发|头n1 | awk的{打印3美元;} | grep - q ' ^安装美元”

This will result in a definitive installed or not-installed

这将导致最终安装或不安装。

#8


2  

$name="rsync"

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

#9


2  

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

这将做它。apt-get安装是等幂的。

sudo apt-get install command

#10


2  

Use:

使用:

apt-cache policy <package_name>

If it is not installed, it will show:

如果没有安装,它将显示:

Installed: none

Otherwise it will show:

否则它将显示:

Installed: version

#11


1  

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

在Ubuntu和Debian中,这个功能已经存在于命令-not-found包中。

#12


1  

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

我已经解决了一个基于Nultyi的答案:

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.

基本上,来自dpkg的错误消息——get-select比大多数其他的都要容易解析,因为它不包括像“deinstall”这样的状态。它还可以同时检查多个包,这是你不能用错误代码做的事情。

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.

因此,grep从列表中移除已安装的包,awk从错误消息中提取包名,导致丢失='python3-venv python3-dev jq',它可以被trivially插入到安装命令中。

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.

我不是盲目地发布一个apt-get安装包,因为在评论中提到,这可能会出乎意料地升级你没有计划的软件包;对于预期稳定的自动化过程来说,这并不是一个好主意。

#13


0  

apt list [packagename]

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

这似乎是在dpkg和更老的apt工具之外最简单的方法。

#14


0  

which <command>
if [ $? == 1 ]; then
    <pkg-manager> -y install <command>
fi

#15


0  

This command is the most memorable:

这个命令是最令人难忘的:

dpkg --get-selections <package-name>

If it's installed it prints:

如果是安装的,它打印:

<package-name> install

<包名称> 安装

Otherwise it prints

否则它打印

No packages found matching <package-name>.

没有找到匹配的包 <包名> 。

This was tested on Ubuntu 12.04.1 (Precise Pangolin).

这是在Ubuntu 12.04.1(精确穿山甲)上测试的。

#16


0  

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

对于Ubuntu, apt提供了一种相当不错的方法。下面是谷歌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.

我将错误输出重定向到null,因为apt警告不要使用它的“不稳定cli”。我怀疑列表包是稳定的,所以我认为扔掉这个警告是可以的。-qq使apt超级安静。