如何将双引号字符串传递给以 sudo 形式执行的函数

如何将双引号字符串传递给以 sudo 形式执行的函数

我正在尝试创建一个脚本,它将添加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"

我这里有两个问题:

  1. 该脚本没有正确地 grep 存储库,因此它总是尝试重新添加存储库。
  2. 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//\"}

最后,用 替换grepfgrep以避免将字符串中的 解释[]为模式。

相关内容