Shell脚本以跳过已安装的PPA

我想创建一个脚本,如果已安装则跳过,否则添加一个新的PPA。
有人在另一个问题中发布了这个解决方案:
#!/bin/bash 

add_ppa() {
      for i in "$@"; do
        grep -h "^deb.*$i" /etc/apt/sources.list.d/* > /dev/null 2>&1
        if [ $? -ne 0 ]
        then
          echo "Adding ppa:$i"
          sudo add-apt-repository -y ppa:$i
        else
          echo "ppa:$i already exists"
        fi
      done
    }

添加APT存储库的Shell脚本

在我的情况下,我想添加ppa:otto-kesselgulasch/gimp-edge,但我不确定应该将其添加到脚本的哪个位置。

我尝试过add_ppa(ppa:otto-kesselgulasch/gimp-edge),但我一直收到一个错误消息(ppa是我的脚本名称):

ppa: 1: ppa: Syntax error: word unexpected (expecting ")")

我还尝试了在ppa之间加上空格,而没有使用括号()

ppa: 1: ppa: add_ppa: not found
ppa: 12: ppa: Syntax error: "}" unexpected

请问有人能告诉我我做错了什么吗?

2编辑您的问题以包含您的脚本将会很有帮助,这样可以更容易地诊断问题所在。 - Arronical
3个回答

这是一个bash函数,要将参数传递给bash函数,你不需要使用()。此外,该函数会在其参数前添加ppa:前缀,所以只需这样写即可:
add_ppa otto-kesselgulasch/gimp-edge

此外,该函数支持多个参数,因此您可以为多个PPA运行它。
add_ppa otto-kesselgulasch/gimp-edge foo/bar a/b

鉴于您已将该函数放在脚本中,您应该选择以下两种方式之一:
  • 按照Zanna的建议,在您的shell中引用它并调用该函数,或者
  • 将函数内容直接作为脚本使用:

    #! /bin/bash
    for i in "$@"; do
      if grep -Rq "^deb.*$i" /etc/apt/sources.list.d/*.list
      then
        echo "正在添加ppa:$i"
        sudo add-apt-repository -y ppa:$i
      else
        echo "ppa:$i 已存在"
      fi
    done
    

    然后使用ppa名称调用脚本:

    ppa otto-kesselgulasch/gimp-edge
    

3有点旁注,您可以省略“在"$@"”;for i; do循环遍历位置参数。 - Kevin

我觉得你把这个文件当作脚本来执行了,但实际上它只是一个函数定义,所以当运行时函数从未被调用。
你不需要对它做任何修改;也不需要在文件中的任何地方添加PPA。你可以使用source命令来加载该文件,并在当前shell中调用该函数。
. ppa
add_ppa otto-kesselgulasch/gimp-edge

假设您将其保存在名为“ppa”的文件中,该文件位于当前工作目录中,并且与您发布的示例具有完全相同的内容。
如果您想将其作为脚本运行,可以添加一行实际调用该函数的代码。您可以通过在末尾添加以下行来将PPA硬编码到其中:
add_ppa otto-kesselgulasch/gimp-edge

然后运行该脚本。但这种方式,您每次想添加新的PPA都需要编辑文件...

相反,您可以通过添加以下一行代码将该函数应用于传递给脚本的所有参数:

add_ppa "$@"

然后当脚本被调用时:

./ppa otto-kesselgulasch/gimp-edge thing/stuff etc/andSoOn

看起来你在脚本中可能打错了字,具体是在add_ppa函数的定义处。
错误信息:
ppa: 1: ppa: add_ppa: not found
ppa: 12: ppa: Syntax error: "}" unexpected

提示add_ppa未被识别为函数。
看起来你可能在定义函数时使用了(而不是{。纠正这个错误,函数应该能正常工作,但应按照muru的答案中所示使用。