Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
3.3k views
in Technique[技术] by (71.8m points)

Veeam CLI Unknown Argument when Passing Arguments in Bash Script

I'm writing a bash script to call functions of the Veeam Backup CLI.

In this script I have a function to configure a new backup job.

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

}

When calling the script I use a case to determine which function shall be called:

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

I call the script like this:

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

I used this site from the Veeam help center to know the arguments: Veeam Help Center: Creating File-Level Backup Job

Calling the script results in an error message

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

If I call veeamconfig manually the command that my echo shows works fine.

Why can I call the command directly but not from within the script? I tried calling the function without the double quotation marks but that doesn't work.

I can't hardcode all arguments like the

--includedirs

so I need to find a way to pass arguments like the

--daily --at 12:15

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The basic problem is that you're passing "--daily --at 12:15" to the veeamconfig command as a single argument, rather than three separate arguments ("--daily", "--at", and "12:15"). This confuses veeamconfig. It looks ok when you echo it because that looses the distinction between spaces between arguments and spaces within arguments.

The best way to handle this depends on a couple of things: First, does your script care which options have to do with scheduling vs indexing vs full backups vs whatever, or is it ok if there's just a list of options to be given to the veeamconfig command? Second, is it possible that the paths/options/whatever might contain spaces (or filename wildcards) in them, as well as between them? (Note: I mostly use macOS, where paths with spaces are very common.)

If the script doesn't have to differentiate between the different types of options, it's pretty simple: just pass all of the options as separate arguments all the way through, and where necessary store them as an array rather than as separate strings (and use bash printf's %q option to properly quote/escape the command options for printing):

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
}

And call it like this:

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

And run the overall script like this:

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

If the script needs to tell the different types of option apart, things get messier. If there's no possibility of spaces or wildcard-like characters in the options, you could leave those variables unquoted when you pass them to the veeamconfig command, and let the shell's word splitting break them up into individual arguments:

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

Note that if you go this route, you need to keep them safely double-quoted at all other points in the process, especially when passing them to the configureBackupJob function. If word-splitting happens too early, it'll just make a mess.

If you need to keep types of options separate and also allow spaces and/or funny characters in the options, it's even more difficult. You might be tempted to put quotes and/or escapes within the options to control this, but word splitting doesn't respect those, so it doesn't work. I think I'll just refer you to this question and hope this doesn't apply.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...