bash
handles the expansion of a quoted parameter as a single token regardless of spaces, tabs, or newlines separating the words originally held in that parameter and therefore it will be wholly passed as a single argument … The same behavior is demonstrated in e.g.:
for f in *; do stat "$f"; done
that passes a filename with spaces, tabs or newlines as a single argument to stat
if the parameter is quoted i.e. "$f"
The right way to split multiple package names held in the parameter packages
and separated by spaces passing them to apt-get
as individual arguments is already mentioned in the answer by @steeldriver as array elements and you will still need to quote the expansion of the array elements as well.
However, ShellCheck is correct and you should listen ... The shell splits words based on the value/s of IFS
... That can be changed with e.g. IFS=-
, then your shell will split words around -
instead of the default space ... Many scripts that you or other users run might change that without you noticing it at all ... and given the fact that you are already utilizing a script for some task, the odds are you are into the habit of scripting things ... Consider this(When you add quotes):
$ command="remove"
packages="python3-pip"
IFS=-; apt-get "$command" -s "$packages"; unset IFS
NOTE: This is only a simulation!
apt-get needs root privileges for real execution.
Keep also in mind that locking is deactivated,
so don't depend on the relevance to the real current situation!
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following packages will be REMOVED:
python3-pip
0 to upgrade, 0 to newly install, 1 to remove and 12 not to upgrade.
Remv python3-pip [22.0.2+dfsg-1ubuntu0.2]
Versus this(When you drop quotes):
$ command="remove"
packages="python3-pip"
IFS=-; apt-get $command -s $packages; unset IFS
NOTE: This is only a simulation!
apt-get needs root privileges for real execution.
Keep also in mind that locking is deactivated,
so don't depend on the relevance to the real current situation!
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
Note, selecting 'python3-pip' instead of 'pip'
The following packages were automatically installed and are no longer required:
checkpolicy fonts-dejavu gdal-data gir1.2-gtk-vnc-2.0 gir1.2-libosinfo-1.0
gir1.2-libvirt-glib-1.0 gir1.2-spiceclientglib-2.0 gir1.2-spiceclientgtk-3.0
libaec0 libarmadillo10 libarpack2 libblosc1 libcfitsio9 libcharls2
libdcmtk16 libembree3-3 libfreexl1 libfyba0 libgdal30 libgdcm3.0
libgeos-c1v5 libgeos3.10.2 libgeotiff5 libgovirt-common libgovirt2
libhdf4-0-alt libhdf5-103-1 libhdf5-hl-100 libjemalloc2 libkmlbase1
libkmldom1 libkmlengine1 liblog4cplus-2.0.5 libnetcdf19 libodbcinst2
libogdi4.1 libopencolorio1v5 libopencv-core4.5d libopencv-imgcodecs4.5d
libopencv-imgproc4.5d libopencv-videoio4.5d libopenimageio2.2 libopenvdb8.1
libosdcpu3.4.4 libproj22 libpugixml1v5 libqhull-r8.0 librttopo1 libsocket++1
libspatialite7 libspnav0 libsquish0 libsuperlu5 libsz2 libtbb2 libtbbmalloc2
libtinyxml2.6.2v5 liburiparser1 libxerces-c3.2 libyaml-cpp0.7
policycoreutils proj-bin proj-data python-babel-localedata python3-pip-whl
python3-setuptools-whl selinux-utils semodule-utils unixodbc-common
virt-viewer
Use 'apt autoremove' to remove them.
The following additional packages will be installed:
libnetplan0 libqt5gui5-gles libqt5quick5-gles policykit-1-gnome
Suggested packages:
qt5-image-formats-plugins
The following packages will be REMOVED:
apport apport-gtk aptdaemon apturl apturl-common blender blender-data
bpfcc-tools chrome-gnome-shell command-not-found csvkit deja-dup dkms
duplicity foomatic-db-compressed-ppds gdm3 gedit gedit-common
gnome-control-center gnome-menus gnome-online-accounts gnome-shell
gnome-shell-extension-appindicator gnome-shell-extension-desktop-icons-ng
gnome-shell-extension-manager gnome-shell-extension-prefs
gnome-shell-extension-system-monitor gnome-shell-extension-ubuntu-dock
gnome-shell-extensions gnome-terminal gnome-tweaks gnome-user-docs
gvfs-backends hplip hplip-data ibus ibus-table language-selector-common
language-selector-gnome libatk-bridge2.0-dev libatk1.0-dev libatspi2.0-dev
libcairo2-dev libgdk-pixbuf-2.0-dev libglib2.0-dev libglib2.0-dev-bin
libgtk-3-dev libharfbuzz-dev libinput-tools libpango1.0-dev libqt5gui5
libqt5opengl5 libqt5opengl5-dev libqt5quick5 libqt5quickwidgets5
libqt5webchannel5-dev libqt5webenginewidgets5 libqwt-qt5-6 libsmbclient
libvulkan-dev libwacom-bin linssid linux-hwe-5.19-tools-5.19.0-35
linux-tools-5.15.0-39 linux-tools-5.15.0-39-generic
linux-tools-5.19.0-35-generic linux-tools-common
linux-tools-virtual-hwe-22.04-edge lsb-release meson
nautilus-extension-gnome-terminal nautilus-share netplan.io
networkd-dispatcher nfs-common openprinting-ppds orca perf-tools-unstable
plymouth-theme-spinner plymouth-theme-ubuntu-text policycoreutils-dev
policycoreutils-python-utils printer-driver-foo2zjs
printer-driver-foo2zjs-common printer-driver-m2300w
printer-driver-postscript-hp printer-driver-ptouch printer-driver-pxljr
printer-driver-sag-gdi python3 python3-agate python3-agatedbf
python3-agateexcel python3-agatesql python3-apport python3-apt
python3-aptdaemon python3-aptdaemon.gtk3widgets python3-attr python3-audit
python3-babel python3-bcrypt python3-blinker python3-bpfcc python3-brlapi
python3-bs4 python3-cairo python3-certifi python3-cffi-backend
python3-chardet python3-click python3-colorama python3-commandnotfound
python3-cryptography python3-csvkit python3-cups python3-cupshelpers
python3-dateutil python3-dbfread python3-dbus python3-debconf python3-debian
python3-decorator python3-defer python3-dev python3-distro
python3-distro-info python3-distupgrade python3-distutils python3-et-xmlfile
python3-fasteners python3-future python3-gdbm python3-gi python3-gi-cairo
python3-greenlet python3-html5lib python3-httplib2 python3-ibus-1.0
python3-icu python3-idna python3-importlib-metadata python3-iniconfig
python3-isodate python3-jdcal python3-jeepney python3-jwt python3-keyring
python3-launchpadlib python3-lazr.restfulclient python3-lazr.uri python3-ldb
python3-leather python3-lib2to3 python3-libevdev python3-libvirt
python3-libxml2 python3-lockfile python3-louis python3-lxml
python3-macaroonbakery python3-mako python3-markupsafe python3-monotonic
python3-more-itertools python3-msgpack python3-nacl python3-neovim
python3-netaddr python3-netifaces python3-networkx python3-numpy
python3-oauthlib python3-olefile python3-openpyxl python3-packaging
python3-paramiko python3-parsedatetime python3-pexpect python3-pil
python3-pip python3-pkg-resources python3-pluggy python3-problem-report
python3-protobuf python3-ptyprocess python3-py python3-pyatspi
python3-pygments python3-pymacaroons python3-pynvim python3-pyparsing
python3-pytest python3-pytimeparse python3-pyudev python3-renderpm
python3-reportlab python3-reportlab-accel python3-requests python3-rfc3339
python3-secretstorage python3-selinux python3-semanage python3-sepolgen
python3-sepolicy python3-setools python3-setuptools python3-six
python3-slugify python3-software-properties python3-soupsieve
python3-speechd python3-sqlalchemy python3-sqlalchemy-ext python3-sss
python3-systemd python3-talloc python3-toml python3-tz python3-unidecode
python3-uno python3-update-manager python3-urllib3 python3-venv
python3-wadllib python3-webencodings python3-wheel python3-xdg python3-xkit
python3-xlrd python3-yaml python3-zipp python3.10-venv python3.11-venv
qtbase5-dev qtdeclarative5-dev qtpositioning5-dev qttools5-dev
qttools5-dev-tools qtwebengine5-dev rhythmbox-plugin-alternative-toolbar
rhythmbox-plugins samba-libs selinux-policy-dev setools
software-properties-common software-properties-gtk ssh-import-id sssd
sssd-ad sssd-ad-common sssd-common sssd-ipa sssd-krb5 sssd-krb5-common
sssd-ldap sssd-proxy system-config-printer system-config-printer-common
system-config-printer-udev totem-plugins ttf-mscorefonts-installer tuptime
ubuntu-advantage-desktop-daemon ubuntu-advantage-tools ubuntu-desktop
ubuntu-desktop-minimal ubuntu-docs ubuntu-drivers-common ubuntu-minimal
ubuntu-release-upgrader-core ubuntu-release-upgrader-gtk ubuntu-session ufw
unattended-upgrades update-manager update-manager-core update-notifier
update-notifier-common usb-creator-common usb-creator-gtk virt-manager
virtinst virtualbox virtualbox-dkms virtualbox-qt vlc-plugin-samba xfsprogs
xorg xserver-xorg yelp
The following NEW packages will be installed:
libqt5gui5-gles libqt5quick5-gles policykit-1-gnome
The following packages will be upgraded:
libnetplan0
1 to upgrade, 3 to newly install, 291 to remove and 10 not to upgrade.
Remv apport-gtk [2.20.11-0ubuntu82.3]
Remv apport [2.20.11-0ubuntu82.3]
Remv ubuntu-desktop [1.481]
Remv ubuntu-desktop-minimal [1.481]
Remv gnome-control-center [1:41.7-0ubuntu0.22.04.6]
Remv language-selector-gnome [0.219.1
.
.
.
etc. The list goes on and on
Are you still wiling to take the risk?
SC2086
- you'll find documentation and suggestions on how to improve your script.