我可以删除重复的 snap 包中的旧版本包吗?

我可以删除重复的 snap 包中的旧版本包吗?

在检查系统中安装的 snap 包时,我注意到一些包有重复,一个包的修订号过高,而另一个包的修订号较新。对于这种重复的包,我的问题是:

  1. 为什么它们会重复?
  2. 我可以删除较旧的包以确保更好地管理磁盘空间吗?
  3. 我该如何删除旧包?

以下是有重复和没有重复的包的示例:

$ du -hcs /var/lib/snapd/snaps/*
31M /var/lib/snapd/snaps/2048x_3.snap
286M    /var/lib/snapd/snaps/atom_282.snap
4.0K    /var/lib/snapd/snaps/bare_5.snap
72M /var/lib/snapd/snaps/bitwarden_58.snap
72M /var/lib/snapd/snaps/bitwarden_59.snap
196M    /var/lib/snapd/snaps/blender_1113.snap
214M    /var/lib/snapd/snaps/blender_1237.snap
9.1M    /var/lib/snapd/snaps/canonical-livepatch_119.snap
9.1M    /var/lib/snapd/snaps/canonical-livepatch_126.snap
148M    /var/lib/snapd/snaps/chromium_1854.snap
148M    /var/lib/snapd/snaps/chromium_1864.snap
17M /var/lib/snapd/snaps/chromium-ffmpeg_23.snap
18M /var/lib/snapd/snaps/chromium-ffmpeg_24.snap
....

~$ ls -lh /var/lib/snapd/snaps/
total 12G
-rw------- 2 root root  31M Aug  5 06:23 2048x_3.snap
-rw------- 2 root root 286M Aug  5 08:35 atom_282.snap
-rw------- 2 root root 4.0K Sep 22 18:17 bare_5.snap
-rw------- 1 root root  72M Oct 30 00:20 bitwarden_58.snap
-rw------- 1 root root  72M Dec  9 04:28 bitwarden_59.snap
-rw------- 1 root root 196M Nov 18 04:06 blender_1113.snap
-rw------- 1 root root 214M Dec  4 09:39 blender_1237.snap
-rw------- 2 root root 9.1M Nov 17 21:06 canonical-livepatch_119.snap
-rw------- 2 root root 9.1M Nov 22 22:39 canonical-livepatch_126.snap
-rw------- 1 root root 148M Dec 16 04:28 chromium_1854.snap
-rw------- 1 root root 148M Jan  8 08:33 chromium_1864.snap
-rw------- 1 root root  17M Sep  3 06:29 chromium-ffmpeg_23.snap
-rw------- 2 root root  18M Nov 29 14:23 chromium-ffmpeg_24.snap
....

在我查看的系统上,使用的总磁盘空间/var/lib/snapd/snaps/*为 12,180.248 MB。所有重复软件包(即同一软件包的旧版本)的磁盘空间为 4,163.1 MB。简而言之,旧版本软件包目前占用了 12,180.248 MB 的 34.18%。这似乎是使用 SNAP 应用程序的成本,我之前没有意识到这一点。

答案1

回答您的问题:

为什么它们会重复?

⇢ 它们是不同的修订版(版本),而不是重复。

我可以删除较旧的包以确保更好地管理磁盘空间吗?

⇢ 是的。你的毕竟,这是计算机。

我该如何删除旧包?

您可以在终端中执行以下操作:

snap remove {snap} --revision={revision}

您还可以告诉系统限制过去版本的数量,如下所示:

sudo snap set system refresh.retain=2

笔记:该值必须介于2和之间,通常建议使用或20这样的数字以节省存储空间并允许在发生错误更新时回滚。23

如果你想列出所有的快照及其版本,你可以运行这个命令:

snap list --all

它会给你类似这样的结果:

Name                 Version                     Rev    Tracking         Publisher   Notes
bare                 1.0                         5      latest/stable    canonical✓  base
canonical-livepatch  10.0.1                      119    latest/stable    canonical✓  disabled
canonical-livepatch  10.1.2                      126    latest/stable    canonical✓  -
core                 16-2.52                     11798  latest/stable    canonical✓  core,disabled
core                 16-2.52.1                   11993  latest/stable    canonical✓  core
core18               20211028                    2253   latest/stable    canonical✓  base
core18               20211015                    2246   latest/stable    canonical✓  base,disabled
core20               20211115                    1242   latest/stable    canonical✓  base,disabled
core20               20211129                    1270   latest/stable    canonical✓  base
gnome-3-28-1804      3.28.0-19-g98f9e67.98f9e67  145    latest/stable    canonical✓  disabled
gnome-3-28-1804      3.28.0-19-g98f9e67.98f9e67  161    latest/stable    canonical✓  -
gnome-3-34-1804      0+git.3556cb3               77     latest/stable/…  canonical✓  -
gnome-3-34-1804      0+git.3556cb3               72     latest/stable/…  canonical✓  disabled
gnome-3-38-2004      0+git.cd626d1               87     latest/stable    canonical✓  -
gnome-3-38-2004      0+git.6ba6040               76     latest/stable    canonical✓  disabled
gtk-common-themes    0.1-52-gb92ac40             1515   latest/stable/…  canonical✓  disabled
gtk-common-themes    0.1-59-g7bca6ae             1519   latest/stable/…  canonical✓  -
snap-store           3.38.0-66-gbd5b8f7          558    latest/stable/…  canonical✓  -
snap-store           3.38.0-64-g23c4c77          547    latest/stable/…  canonical✓  disabled
snapd                2.53.2                      14066  latest/stable    canonical✓  snapd,disabled
snapd                2.53.4                      14295  latest/stable    canonical✓  snapd

需要脚本吗?

重要的:在继续之前,您需要检查snap list --all计算机上的输出,如果您使用的语言环境是:不是 en_US.UTF-8

剧本:

#!/bin/bash
# This script will remove disabled snap revisions.
set -eu

LANG=C snap list --all | awk '/disabled/{print $1, $3}' |
    while read name rev; do
        snap remove "$name" --revision="$rev"
    done

这将运行snap list -all并提取包含单词 的行disabled。这将根据您所在地区的不同而有所不同,因此请检查函数的输出第一的,然后更新awk '/disabled/以替换disabled在输出中找到的标签。

将脚本保存到文件(例如scrub-snaps.sh),然后将其设置为可执行文件:

sudo chmod +x scrub-snaps.sh

现在你可以运行它了,记得使用sudo

sudo ./scrub-snaps.sh

笔记: sudo不是脚本的一部分,但如果您愿意,可以添加它。无论哪种方式,如果需要,系统都会提示您输入密码。

答案2

保留至少一个旧版本的 snap 是设计中固有的。

Snap 软件包最初是为各种环境设计的,这些环境通常没有人工管理员和/或无法连接键盘和显示器……例如手机或物联网设备。弹性是这些系统的关键要求:如果应用程序崩溃或升级损坏,则需要某种形式的保证回滚而无需人工干预。因此,至少需要一个旧版本。

传统台式机和服务器用户不太关心回滚功能。他们喜欢不同的 snap 设计元素:独立于操作系统的安全自动升级、只读 squashfs 防篡改、进程限制等。

但由于都是单一标准,所以您也拥有回滚功能。即使您认为自己不会使用它。

您无法“禁用”快照的回滚功能——它实际上不是一个“功能”,而是一个关键的设计元素。

答案3

基于@matigo 的回答,我写了一篇python 脚本自动删除已禁用的 SNAP 包。它允许用户在继续(或不继续)删除过程之前目视检查 snap 包。链接中显示了执行脚本的示例。

删除已禁用的 snap 包.py

#!/bin/python3
''' This python script automates the removal of all disabled SNAP packages in
a system. Doing so helps free up the system's disk space. This outcome can be
significant in the situation where many disabled SNAP packages are retained in
the system.
'''
from subprocess import run, PIPE, CalledProcessError
from pathlib import Path
import sys

# Assumptions
SNAP_PKGS_PATH = Path('/var/lib/snapd/snaps/')
# Also, at a minimum, this directory has at least one xxx.snap file there. 


def snap_list():
    '''Function to execute a bash 'snap list' cmd and returns a Python
    dictionary of info of the ACTIVE SNAPCRAFT pkgs in the system.

    pkgs_dict = {Name : {'Version':'xxx', 'Rev':'xxx', 'Tracking':'xxx',
                         'Publisher':'xxx', 'Notes':'xxx'}
                }
    '''
    try:
        cmd = ['snap', 'list']
        completed = run(cmd, check=True, stdout=PIPE)
    except CalledProcessError as err:
        print('ERROR:', err)
    else:
        headers = completed.stdout.decode('utf-8').splitlines()[0].split()
        pkgs=[line.split() for line in
              completed.stdout.decode('utf-8').splitlines()[1:]]
        pkgs_dict = {}
        for pkg in pkgs:
            pkgs_dict[pkg[0]] = {i:pkg[n+1] for n, i in enumerate(headers[1:])}
        return pkgs_dict


# 1. Get all SNAPCRAFT pkgs in system
all_path = sorted(SNAP_PKGS_PATH.glob('*.snap'))
all_size = sum([p.stat().st_size for p in all_path])

# 2. Get active SNAPCRAFT pkgs in system
active_snap_pkgs = snap_list()
active_path = [SNAP_PKGS_PATH / Path(k+'_'+v['Rev']+'.snap')
               for k, v in active_snap_pkgs.items()]
active_size = sum([p.stat().st_size for p in active_path])

# 3. Display info and instructions in terminal
print(f'ALL (ACTIVE & DISABLED) SNAP PACKAGES IN SYSTEM:')
for n, i in enumerate(all_path):
    size = i.stat().st_size
    if i in active_path:
        print(f'Active\t{size:>12}\t{i}')
    else:
        print(f'      \t{size:>12}\t{i}')

# 4. Show stats on total size of All, Active & Disabled SNAPCRAFT packages 
width = 12
disabled_size = all_size - active_size
print('\nSIZE OF SNAP PACKAGES:')
print(f'1. All      : {all_size:>{width}} bytes')
print(f'2. Active   : {active_size:>{width}} bytes')
print(f'2. Disabled : {disabled_size:>{width}} bytes or '
      f'{(disabled_size/all_size):.2%} of All')

# 5. Make decision to remove or not to remove Disabled SNAPCRAFT packages 
if disabled_size > 0:
    print(f'\nREMOVE ALL DISABLED SNAP PACKAGES? [y/n]')
    while True:
        decision = input()
        if decision in ['y', 'Y', 'yes', 'Yes', 'YES']:
            print('Removal in progress... pls wait')
            for p in all_path:
                if p not in active_path:
                    stem = p.stem
                    bar_index = stem.index('_')
                    name = stem[:bar_index]
                    revision = stem[bar_index+1:]
                    cmd = ['sudo', 'snap', 'remove', name,
                           '--revision='+revision]
                    print(f"\n{' '.join(cmd)}")
                    run(cmd, stdout=sys.stdout, stderr=sys.stderr,
                        encoding='utf8')
            print(f'\nREMOVE ALL DISABLED SNAP PACKAGES? COMPLETED.')
            break
        elif decision in ['n', 'N', 'no', 'No', 'NO']:
            print(f'\nNO REMOVAL IS PERFORMED.')
            break
        else:
            print('Please enter only "y" or "n":')
else:
    print(f'\nNO REMOVAL IS NEEDED.')

答案4

(写这些是为了在脚本不起作用时提供额外的背景信息)

对我来说,运行上述脚本不会对 snapds 的大小造成太大的改变。

因此我检查了我拥有的文件: sudo ls -l /var/lib/snapd/snaps

并将旧的未使用的快照移至备份目录,fe: sudo mv /var/lib/snapd/snaps/brave_2*.snap ~/Programming

然后我重新启动了机器,看看一切是否正常,然后删除了备份文件。

通过这样做,我能够恢复大约 4GB。

相关内容