如何从PPA中挑选所需的软件包?

有没有办法从你添加的ppa存储库中挑选出特定的软件包?也就是说,可以在更新时排除某些软件包,同时包含其他软件包吗?
例如,我只想要这个存储库中的chromium-browser软件包,而不需要其他软件包。因此,我不希望通过sudo apt-get upgrade命令安装该ppa存储库中除了chromium-browser以外的其他软件包,只需要这一个软件包。
我意识到如果我误读依赖关系并排除了一些必需的软件包,可能会给自己带来麻烦,但我确切知道在这种情况下其他软件包并不是chromium-browser的依赖项。
这种做法是否可行?也许有某种白名单/黑名单文件之类的东西吗?

我不会选择使用Synaptic,有三个原因:首先,Ubuntu已经将其作为软件更新器放弃了,转而支持Ubuntu软件中心;其次,我没有找到Synaptic停止从ppa升级已安装文件的方法(这是我的问题);最后,我更喜欢命令行解决方案而不是图形界面。最终,我找到了一个可行的解决方案(请参见下面的回答)。 - yuvilio
2软件中心用于安装和卸载软件,更新管理器用于更新。你可以在Synaptic中使用固定功能,这样其他软件包就不会升级了。对于不想与终端打交道的新用户来说,图形界面是首选,当然你的回答基本上是正确的。 - Uri Herrera
有一些事情你在软件中心无法做到(但在Synaptic上很容易)。而且,并不是每个人(尤其是新手)都习惯使用命令行。 - Mrokii
@Mrokii 我同意我的方法不适合初学者。你写的Synaptic答案和Uri Herrera提到的方法,我认为是更好的选择。我会让其他尝试过的人来评价它。 - yuvilio
3个回答

找到了一种方法。

诀窍是使用两个固定从句。第一个是禁止从PPA安装所有软件包,第二个是选择您想要的软件包。

因此,对于上面的示例,我首先像往常一样添加ppa:

$ sudo add-apt-repository ppa:webapps/preview
...
$ sudo apt-get update
...

现在如果我运行apt-cache policy,它会显示有一个更新版本的chromium-browser可用,并且它将通过升级安装,因为它与我的当前chromium-browser具有相同的优先级(500)。
$ sudo apt-cache policy chromium-browser
chromium-browser:
  Installed: 18.0.1025.168~r134367-0ubuntu0.12.04.1
  Candidate: 20.0.1132.47~r144678-0precise1+webapps3
  Version table:
     20.0.1132.47~r144678-0precise1+webapps3 0
        500 http://ppa.launchpad.net/webapps/preview/ubuntu/ precise/main amd64 Packages
 *** 18.0.1025.168~r134367-0ubuntu0.12.04.1 0
        500 http://us.archive.ubuntu.com/ubuntu/ precise-updates/universe amd64 Packages
        500 http://security.ubuntu.com/ubuntu/ precise-security/universe amd64 Packages
        500 http://ppa.launchpad.net/chromium-daily/beta/ubuntu/ precise/main amd64 Packages
        100 /var/lib/dpkg/status
     18.0.1025.151~r130497-0ubuntu1 0
        500 http://us.archive.ubuntu.com/ubuntu/ precise/universe amd64 Packages
E: Unable to parse package file /etc/apt/preferences.d/webapps-preview-pin-400 (1)
$ 

这个包还不错,但我不想安装这个ppa中的其他包(它们也有500的优先级)。如果我现在尝试升级,我会从该软件源获取到更多不只是我想要的chromium包。
$ sudo apt-get upgrade
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following packages have been kept back:
  bamfdaemon gwibber gwibber-service gwibber-service-facebook gwibber-service-twitter indicator-appmenu libbamf0 libbamf3-0 shotwell
The following packages will be upgraded:
  chromium-browser chromium-browser-l10n chromium-codecs-ffmpeg gwibber-service-identica indicator-messages indicator-status-provider-mc5
  indicator-status-provider-pidgin libindicator-messages-status-provider1
8 upgraded, 0 newly installed, 0 to remove and 9 not upgraded.
Need to get 25.3 MB of archives.
After this operation, 5,034 kB of additional disk space will be used.
Do you want to continue [Y/n]? 

所以我可以告诉apt,我希望那个ppa中的所有软件包,这里是webapps-preview,除了名字中带有"chromium"的软件包之外,都具有较低的优先级。实现这一机制的方法是固定一个软件包
我在/etc/apt/preferences.d/目录下创建了一个文件,其中包含两个子句。第一个子句表示给webapps-preview ppa中的所有软件包一个比普通软件包更低的优先级(即使它们具有更高的版本号,也不会被优先选择)。第二个子句部分地覆盖了第一个子句,它表示给那个ppa中名字中带有"chromium"的软件包与其他软件包相同的优先级,以便安装该软件包(因为它具有更高的版本号)。
$ cat /etc/apt/preferences.d/webapps-preview-pin-400
Package:  *
Pin: release o=LP-PPA-webapps-preview
Pin-Priority: 400


Package:  *chromium*
Pin: release o=LP-PPA-webapps-preview
Pin-Priority: 500

要识别“Pin: release”选项的正确字符串,我们可以再次使用apt-cache policy。
$ apt-cache policy
...
500 http://ppa.launchpad.net/webapps/preview/ubuntu/ precise/main i386 Packages
    release v=12.04,o=LP-PPA-webapps-preview,a=precise,n=precise,l=preview,c=main
    origin ppa.launchpad.net
...

对于apt版本小于0.8.14的情况,必须明确指定固定的软件包,因为通配符无法使用。
$ cat /etc/apt/preferences.d/webapps-preview-pin-400
Package:  *
Pin: release o=LP-PPA-webapps-preview
Pin-Priority: 400


Package:  chromium-browser chromium-codecs-ffmpeg chromium-browser-l10n chromium-codecs-ffmpeg-extra
Pin: release o=LP-PPA-webapps-preview
Pin-Priority: 500

现在,当我尝试升级时,我只从那个ppa获取我想要的软件包,而不是其他的。所有的软件包都为我精心挑选好了。
$ sudo apt-get upgrade
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following packages will be upgraded:
  chromium-browser chromium-browser-l10n chromium-codecs-ffmpeg
3 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
Need to get 25.1 MB of archives.
After this operation, 5,026 kB of additional disk space will be used.
Do you want to continue [Y/n]?

6相当复杂,以我个人看法。 - Mrokii
5我不同意,这对于某人喜欢的东西来说相当简单明了。而且很好,所有关于识别ppa的引脚名称的说明都在那里。 - Nicholi
这个具体的答案适用于那些希望确保apt始终优先选择特定软件源中的软件包的人。如果你只需要一次性解决方案,可以尝试这个答案或者这个答案 - Braiam

你还可以使用?origin选择器来选择要安装的发行版:

匹配发行版源与正则表达式 origin 匹配的软件包版本。例如,"!?origin(debian)" 将找到系统中任何非官方的软件包(即不是来自 Debian 软件源的软件包)。

所以,在您的特定情况下,您可以使用:
sudo aptitude install !?origin(LP-PPA-webapps-preview) chromium

或者你可以使用<packagename>=<version>来指定版本:

sudo apt-get install chromium=20.0.1132.47~r144678-0precise1+webapps3

您可以通过Synaptic实际上“挑选”某些软件包,而且非常容易。它的工作原理如下:
  • 如果您只想对某些PPA执行此操作,请在Synaptic窗口中选择“Origin”(左下角),然后选择要更改的PPA

  • 选择所有您不想自动升级的软件包。

  • 选择菜单“Package/Lock Version”。您选择的所有软件包将不再自动升级,直到您再次解锁它们。