Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save aont/f6ca32804dc29b912c291f528e2b05cb to your computer and use it in GitHub Desktop.
Save aont/f6ca32804dc29b912c291f528e2b05cb to your computer and use it in GitHub Desktop.

Safe Package Removal Script with Protection Check

Purpose

This script automates the removal of packages listed in one file (to_be_removed.txt), but skips removal if doing so would also remove any "protected" packages listed in another file (keep.txt). It ensures important packages are not accidentally uninstalled.

Usage

  1. Prepare two text files:

    • to_be_removed.txt: Packages you want to remove (one per line)
    • keep.txt: Packages that must not be removed (protected packages)
  2. Run the script in a bash environment. It will simulate removal for each package in to_be_removed.tx.

  3. If any protected package would be removed as a side effect, the script skips removing that package.

  4. Otherwise, it proceeds to remove the package using apt-get remove -y.

ubuntu-wsl
wsl-pro-service
wsl-setup
#!/bin/bash
fileA='to_be_removed.txt'
fileB='keep.txt'
declare -A protect_pkgs
while IFS= read -r line; do
[[ -n "$line" ]] && protect_pkgs["$line"]=1
done < "$fileB"
declare -a candidates
while IFS= read -r pkg; do
[[ -z "$pkg" ]] && continue
# シミュレーションで削除されるパッケージ一覧を取得
echo "[info] Check packages to be removed for: $pkg"
to_remove=$(apt-get remove --simulate "$pkg" | grep ^Remv | awk '{print $2}')
if [[ -z "$to_remove" ]]; then
echo "[info] No packages will be removed for: $pkg"
continue
fi
# 保護パッケージが含まれていればスキップ
skip=0
for p in $to_remove; do
if [[ ${protect_pkgs[$p]} ]]; then
echo "[info] Skipping $pkg because protected package '$p' would be removed"
skip=1
break
fi
done
if [[ $skip -eq 0 ]]; then
candidates+=("$pkg")
fi
done < "$fileA"
if [[ ${#candidates[@]} -eq 0 ]]; then
echo "[info] No packages to remove."
exit 0
fi
# 一括シミュレーション
# echo "Packages to be removed in one operation: ${candidates[*]}"
# final_to_remove=$(apt-get remove --simulate "${candidates[@]}" | grep ^Remv | awk '{print $2}')
# 最終的に保護対象が含まれるか再チェック(念のため)
# for p in $final_to_remove; do
# if [[ ${protect_pkgs[$p]} ]]; then
# echo "Aborting: protected package '$p' would be removed in batch."
# exit 1
# fi
# done
# 一括削除実行
echo "Removing packages: ${candidates[*]}"
apt-get remove -y "${candidates[@]}"
apt-get clean
adduser
adwaita-icon-theme
apparmor
apport
apport-core-dump-handler
apport-symptoms
appstream
apt-utils
at-spi2-common
at-spi2-core
bash-completion
bc
binutils
binutils-common
binutils-x86-64-linux-gnu
bsdextrautils
byobu
ca-certificates
cloud-guest-utils
cloud-init
command-not-found
console-setup
console-setup-linux
cron
cron-daemon-common
curl
dbus
dbus-bin
dbus-daemon
dbus-session-bus-common
dbus-system-bus-common
dbus-user-session
dbus-x11
dconf-gsettings-backend
dconf-service
dhcpcd-base
dirmngr
distro-info
distro-info-data
e2fsprogs-l10n
eatmydata
ed
eject
fdisk
file
fontconfig
fontconfig-config
fonts-dejavu-core
fonts-dejavu-mono
fonts-ubuntu
fuse3
gawk
gdisk
gettext-base
gir1.2-girepository-2.0
gir1.2-glib-2.0
gir1.2-packagekitglib-1.0
git
git-man
gnupg
gnupg-l10n
gnupg-utils
gpg
gpg-agent
gpgconf
gpgsm
gpg-wks-client
groff-base
gsettings-desktop-schemas
gtk-update-icon-cache
hicolor-icon-theme
humanity-icon-theme
ibverbs-providers
ifuse
info
install-info
iproute2
iso-codes
kbd
keyboard-configuration
keyboxd
krb5-locales
landscape-client
landscape-common
libappstream5
libatk1.0-0t64
libatk-bridge2.0-0t64
libatm1t64
libatspi2.0-0t64
libavahi-client3
libavahi-common3
libavahi-common-data
libbinutils
libbpf1
libbrotli1
libcairo2
libcairo-gobject2
libcbor0.10
libcolord2
libctf0
libctf-nobfd0
libcups2t64
libcurl3t64-gnutls
libcurl4t64
libdatrie1
libdb5.3t64
libdbus-1-3
libdconf1
libdeflate0
libdrm2
libdrm-amdgpu1
libdrm-common
libdrm-intel1
libdrm-nouveau2
libdrm-radeon1
libduktape207
libdw1t64
libeatmydata1
libegl1
libegl-mesa0
libelf1t64
libepoxy0
liberror-perl
libevent-core-2.1-7t64
libexpat1
libfido2-1
libfontconfig1
libfreetype6
libfribidi0
libfuse2t64
libfuse3-3
libgbm1
libgdbm6t64
libgdbm-compat4t64
libgdk-pixbuf-2.0-0
libgdk-pixbuf2.0-bin
libgdk-pixbuf2.0-common
libgirepository-1.0-1
libgl1
libgl1-amber-dri
libgl1-mesa-dri
libglapi-mesa
libglib2.0-0t64
libglib2.0-bin
libglib2.0-data
libglvnd0
libglx0
libglx-mesa0
libgpg-error-l10n
libgpm2
libgprofng0
libgraphite2-3
libgstreamer1.0-0
libgtk-3-0t64
libgtk-3-bin
libgtk-3-common
libharfbuzz0b
libibverbs1
libicu74
libjbig0
libjpeg8
libjpeg-turbo8
libksba8
liblcms2-2
libldap2
libldap-common
liblerc4
libllvm17t64
liblzo2-2
libmagic1t64
libmagic-mgc
libmpfr6
libnetplan1
libnghttp2-14
libnl-3-200
libnl-route-3-200
libnss-systemd
libpackagekit-glib2-18
libpam-cap
libpam-systemd
libpango-1.0-0
libpangocairo-1.0-0
libpangoft2-1.0-0
libpcap0.8t64
libpciaccess0
libperl5.38t64
libpipeline1
libpixman-1-0
libplist-2.0-4
libpng16-16t64
libpolkit-agent-1-0
libpolkit-gobject-1-0
libproc2-0
libpsl5t64
libpython3.12-minimal
libpython3.12-stdlib
libpython3.12t64
libpython3-stdlib
libreadline8t64
librsvg2-2
librsvg2-common
librtmp1
libsasl2-2
libsasl2-modules
libsasl2-modules-db
libsemanage2
libsensors5
libsensors-config
libsepol2
libsframe1
libsharpyuv0
libsigsegv2
libsodium23
libsqlite3-0
libssh-4
libstemmer0d
libthai0
libthai-data
libtiff6
libtirpc3t64
libuchardet0
libunwind8
libusb-1.0-0
libutempter0
libvulkan1
libwayland-client0
libwayland-cursor0
libwayland-egl1
libwayland-server0
libwebp7
libx11-6
libx11-data
libx11-xcb1
libxau6
libxcb1
libxcb-dri2-0
libxcb-dri3-0
libxcb-glx0
libxcb-present0
libxcb-randr0
libxcb-render0
libxcb-shm0
libxcb-sync1
libxcb-xfixes0
libxcomposite1
libxcursor1
libxdamage1
libxdmcp6
libxext6
libxfixes3
libxi6
libxinerama1
libxkbcommon0
libxml2
libxmlb2
libxmuu1
libxrandr2
libxrender1
libxshmfence1
libxtst6
libxxf86vm1
libyaml-0-2
lsb-release
lshw
lsof
man-db
manpages
media-types
mesa-vulkan-drivers
motd-news-config
netcat-openbsd
netplan.io
netplan-generator
networkd-dispatcher
openssh-client
openssl
packagekit
packagekit-tools
passwd
pastebinit
patch
pci.ids
perl
perl-modules-5.38
pinentry-curses
polkitd
ppp
procps
psmisc
publicsuffix
python3
python3.12
python3.12-minimal
python3.12-venv
python3-apport
python3-apt
python3-attr
python3-automat
python3-babel
python3-bcrypt
python3-blinker
python3-certifi
python3-cffi-backend
python3-chardet
python3-click
python3-colorama
python3-commandnotfound
python3-configobj
python3-constantly
python3-cryptography
python3-dbus
python3-debconf
python3-distro
python3-distro-info
python3-distupgrade
python3-gdbm
python3-gi
python3-hamcrest
python3-httplib2
python3-hyperlink
python3-idna
python3-incremental
python3-jinja2
python3-jsonpatch
python3-json-pointer
python3-jsonschema
python3-jwt
python3-launchpadlib
python3-lazr.restfulclient
python3-lazr.uri
python3-markdown-it
python3-markupsafe
python3-mdurl
python3-minimal
python3-netifaces
python3-netplan
python3-newt
python3-oauthlib
python3-openssl
python3-pip-whl
python3-pkg-resources
python3-problem-report
python3-pyasn1
python3-pyasn1-modules
python3-pycurl
python3-pygments
python3-pyparsing
python3-pyrsistent
python3-requests
python3-rich
python3-serial
python3-service-identity
python3-setuptools
python3-setuptools-whl
python3-six
python3-software-properties
python3-systemd
python3-twisted
python3-typing-extensions
python3-tz
python3-update-manager
python3-urllib3
python3-wadllib
python3-yaml
python3-zope.interface
python-apt-common
python-babel-localedata
rsync
rsyslog
run-one
session-migration
sgml-base
shared-mime-info
show-motd
snapd
software-properties-common
squashfs-tools
systemd-hwe-hwdb
systemd-resolved
systemd-timesyncd
time
tmux
ubuntu-minimal
ubuntu-mono
ubuntu-pro-client
ubuntu-pro-client-l10n
ubuntu-release-upgrader-core
ucf
unattended-upgrades
update-manager-core
update-motd
usb.ids
usbmuxd
usbutils
uuid-runtime
vim
vim-runtime
wget
x11-common
xauth
xdg-user-dirs
xkb-data
xml-core
xz-utils
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment