![如何将双引号字符串传递给以 sudo 形式执行的函数](https://linux22.com/image/1020340/%E5%A6%82%E4%BD%95%E5%B0%86%E5%8F%8C%E5%BC%95%E5%8F%B7%E5%AD%97%E7%AC%A6%E4%B8%B2%E4%BC%A0%E9%80%92%E7%BB%99%E4%BB%A5%20sudo%20%E5%BD%A2%E5%BC%8F%E6%89%A7%E8%A1%8C%E7%9A%84%E5%87%BD%E6%95%B0.png)
我正在尝试创建一个脚本,它将添加deb http://repo.tld/ubuntu distro component
文件中列出的常规 apt 存储库。
我有一个检查 sudo 状态的函数,以确保命令以 sudo 身份运行。
superdo() {
# do some checks and prompt user for password if he is not logged in as sudo
# execute the command passed in as an argument
sudo $@
}
这个函数从如下列表中读取 repos:
#package-name|key|"repo"
vscode|https://packages.microsoft.com/keys/microsoft.asc|"deb [arch=amd64] https://packages.microsoft.com/repos/vscode stable main"
功能:
# ${1} = list-name
# ${2} = https://key.example.com/signing-key-pub.gpg
# ${3} = "deb https://repo.example.com/linux apt/repo"
add_apt_repo() {
# Check if repo already exists
if ! grep -q "${3}" /etc/apt/sources.list /etc/apt/sources.list.d/*; then
superdo "apt-key adv --fetch-keys ${2}"
superdo "add-apt-repository -y ${3}"
else
echo "${1} repository already exists."
fi
}
list="path_to_list_file"
while read line || [[ -n "$line" ]]; do
# skip commented lines.
[[ $line = \#* ]] && continue
IFS='|' read package key repo <<< $line
add_apt_repo "$package" "$key" "$repo"
done <"$list"
我这里有两个问题:
- 该脚本没有正确地 grep 存储库,因此它总是尝试重新添加存储库。
- 该
repository
变量没有连同它的引号一起传递给$@
函数superdo
,所以我总是出现以下错误:
Error: need a single repository as argument
我尝试set -x
查看命令是如何执行的,并得到以下结果:
+ sudo add-apt-repository -y '"deb' http://www.scootersoftware.com/ bcompare4 'non-free"'
答案1
似乎您希望将$3
值保留为单个字符串,而不是按空格拆分。首先,正如steeldriver在评论中所说,您必须使用
sudo "$@"
这意味着你必须打电话
superdo apt-key adv --fetch-keys "${2}"
superdo add-apt-repository -y "${3}"
您会发现,问题在于,您最终add-apt-repository
会收到一个包含文件中双引号的字符串。您需要删除这些双引号。例如,在IFS=... read
添加
repo=${repo//\"}
最后,用 替换grep
,fgrep
以避免将字符串中的 解释[]
为模式。