我使用 Debian GNU/Linux 8 Jessie,并尝试从 shell 变量在 bash 脚本中安装具有 aptitude 的软件包。 shell 变量被解释为单个包“pkg1 pkg2 pkg3 ...”并且未找到,或者仅解析列表中的第一个包。
#!/usr/bin/env bash
set -euo pipefail
IFS=$'\n\t'
# being treated as a single package with spaces in the name
# package "git gist curl build-essential cmake " not found
apt_packages="$(cat packages.txt | grep -Ev '^$|^#' | tr '\n' ' ')"
# only the first package (git) in the list is parsed and installed
apt_packages=( "$(cat packages.txt | grep -Ev '^$|^#')" )
aptitude install "$apt_packages"
这packages.txt
就是你想象的那样:
git
gist
curl
# build from source
build-essential
cmake
答案1
删除 中的注释后packages.txt
,您将得到一个以空格分隔的包名称列表。有一个 shell 运算符可将字符串拆分为以空格分隔的部分:不带引号的变量或命令替换。不带引号的扩展实际上是“split+glob”运算符:它将扩展的结果视为一个列表全局模式哪些是有待扩展的。但由于 deb 包名称不包含任何 shell 通配符,因此 glob 步骤不会执行任何操作,因此您可以使用 split+glob 运算符。
默认情况下,空格和换行符都是有效的分隔符,因此您不需要将换行符转换为空格。保持默认即可IFS
。而且您也不需要去除空白行,因为多个分隔符与一个分隔符一样好(当分隔符为空格时)。
aptitude install $(grep -v '^#' packages.txt)