在 Bash 脚本中传递参数时 Veeam CLI 未知参数

Veeam CLI Unknown Argument when Passing Arguments in Bash Script

我正在编写 bash 脚本来调用 Veeam Backup CLI 的功能。

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

function configureBackupJob() {

    jobname=""
    reponame=""
    objects=""
    advancedOptions=""
    scheduleOptions=""
    activeFullBackupOptions=""
    indexingOptions=""


    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 "" "" "" "" "" "" ""
        ;;
    *)
        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

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

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

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

function configureBackupJob() {

    jobname=""
    reponame=""
    object=""
    allOptions=("${@:4}")    # This stores all arguments starting with  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 函数时。如果分词太早,只会弄得一团糟。

如果您需要将选项的类型分开 并且 还允许在选项中使用空格 and/or 有趣的字符,那就更难了。您可能想在选项中使用引号 and/or 转义来控制这一点,但分词不考虑这些,因此它不起作用。我想我只会向您推荐 this question,希望这不适用。