【问题标题】:Veeam CLI Unknown Argument when Passing Arguments in Bash Script在 Bash 脚本中传递参数时出现 Veeam CLI 未知参数
【发布时间】:2021-04-17 15:01:43
【问题描述】:

我正在编写一个 bash 脚本来调用 Veeam Backup CLI 的函数。

在这个脚本中,我有一个配置新备份作业的功能。

function configureBackupJob() {

    jobname="$1"
    reponame="$2"
    objects="$3"
    advancedOptions="$4"
    scheduleOptions="$5"
    activeFullBackupOptions="$6"
    indexingOptions="$7"


    command="veeamconfig job create filelevel --name ${jobname} --reponame ${reponame} --includedirs ${objects} ${advancedOptions} ${scheduleOptions} ${activeFullBackupOptions} ${indexingOptions} --nosnap"
    echo "${command}"

    veeamconfig job create filelevel --name "$jobname" --reponame "$reponame" --includedirs "$objects" "$advancedOptions" "$scheduleOptions" "$activeFullBackupOptions" "$indexingOptions" --nosnap

}

在调用脚本时,我使用一个案例来确定应该调用哪个函数:

case $command in
    # More cases before and after this one
    configureBackupJob)
        configureBackupJob "$2" "$3" "$4" "$5" "$6" "$7" "$8"
        ;;
    *)
        showHelp
        ;;
esac

我这样调用脚本:

sudo ./script.sh configureBackupJob "TheJobsName" "RepositoryName" "/path/FoldertoBeBackedUpByVeeam"  "--daily --at 12:15" "--weekdays-full Monday,Wednesday" "--indexall"

我使用 Veeam 帮助中心的这个网站来了解这些参数:Veeam Help Center: Creating File-Level Backup Job

调用脚本会导致错误消息

Unknown argument: [--daily --at 12:15].

如果我手动调用 veeamconfig,我的 echo 显示的命令可以正常工作。

为什么我可以直接调用命令而不是从脚本中调用?我尝试在没有双引号的情况下调用该函数,但这不起作用。

我无法对所有参数进行硬编码,例如

--includedirs

所以我需要找到一种方法来传递参数,例如

--daily --at 12:15

【问题讨论】:

    标签: bash veeam


    【解决方案1】:

    基本问题是您将“--daily --at 12:15”作为单个参数传递给veeamconfig 命令,而不是三个单独的参数(“--daily”、“--at”和“@987654326” @")。这让veeamconfig 感到困惑。当您 echo 时,它看起来没问题,因为这失去了 between 参数之间的空格和空格 within 参数之间的区别。

    处理此问题的最佳方法取决于几件事:首先,您的脚本是否关心哪些选项与调度、索引、完整备份以及其他任何事情有关,或者如果只有一个选项列表就可以了给veeamconfig 命令?其次,路径/选项/任何内容是否可能包含空格(或文件名通配符)中,以及它们之间? (注意:我主要使用 macOS,其中带空格的路径很常见。)

    如果脚本不需要区分不同类型的选项,这很简单:只需将所有选项作为单独的参数一直传递,并在必要时将它们存储为数组而不是单独的字符串(并使用 bash printf%q 选项正确引用/转义打印命令选项):

    function configureBackupJob() {
    
        jobname="$1"
        reponame="$2"
        object="$3"
        allOptions=("${@:4}")    # This stores all arguments starting with $4 in an array
    
        printf -v command '%q ' veeamconfig job create filelevel --name "$jobname" --reponame "$reponame" --includedirs "$object" "${allOptions[@]}" --nosnap
        echo "${command}"
    
        veeamconfig job create filelevel --name "$jobname" --reponame "$reponame" --includedirs "$object" "${allOptions[@]}" --nosnap
    }
    

    然后这样称呼它:

    case $command in
        # More cases before and after this one
        configureBackupJob)
            configureBackupJob "${@:2}"
            ...
    

    然后像这样运行整个脚本:

    sudo ./script.sh configureBackupJob "TheJobsName" "RepositoryName" "/path/FoldertoBeBackedUpByVeeam"  --daily --at 12:15 --weekdays-full Monday,Wednesday --indexall
    

    如果脚本需要区分不同类型的选项,事情就会变得更加混乱。如果选项中不可能有空格或类似通配符的字符,则可以在将这些变量传递给 veeamconfig 命令时不加引号,并让 shell 的分词将它们分解为单独的参数:

    veeamconfig job create filelevel --name "$jobname" --reponame "$reponame" --includedirs "$objects" $advancedOptions $scheduleOptions $activeFullBackupOptions $indexingOptions --nosnap
    

    请注意,如果您走这条路线,则需要在流程中的所有其他点安全地使用双引号,尤其是在将它们传递给 configureBackupJob 函数时。如果分词发生得太早,只会弄得一团糟。

    如果您需要将选项类型分开并且还允许选项中包含空格和/或有趣的字符,那就更加困难了。您可能很想在选项中添加引号和/或转义符来控制它,但分词不尊重这些,因此它不起作用。我想我会把你推荐给this question,希望这不适用。

    【讨论】:

    • 第一个解决方案完美运行!非常感谢 Gordon 的帮助,非常感谢!
    猜你喜欢
    • 1970-01-01
    • 2020-09-04
    • 2018-02-12
    • 1970-01-01
    • 2018-03-03
    • 2021-11-18
    • 2012-12-29
    • 2011-11-14
    • 2015-12-31
    相关资源
    最近更新 更多