Why do bash parameter expansions cause an rsync command to operate differently?

后端 未结 2 1254
猫巷女王i
猫巷女王i 2020-12-21 11:47

I am attempting to run an rsync command that will copy files to a new location. If I run the rsync command directly, without any parameter expansions on the command line, r

相关标签:
2条回答
  • 2020-12-21 12:03

    I like to break the arguments onto separate lines, for convenience sake:

    ROPTIONS=(
       -aNHXxEh
       --delete
       --fileflags
       --exclude-from=$EXCLUDELIST
       --delete-excluded
       --force-change
       --stats
       --protect-args
    )
    

    and then call it thusly:

    rsync "${ROPTIONS[@]}" "$SOURCE" "$DESTINATION"
    
    0 讨论(0)
  • 2020-12-21 12:04

    The shell parses quotes before expanding variables, so putting quotes in a variable's value doesn't do what you expect -- by the time they're in place, it's too late for them to do anything useful. See BashFAQ #50: I'm trying to put a command in a variable, but the complex cases always fail! for more details.

    In your case, it looks like the easiest way around this problem is to use an array rather than a plain text variable. This way, the quotes get parsed when the array is created, each "word" gets stored as a separate array element, and if you reference the variable properly (with double-quotes and [@]), the array elements get included in the command's argument list without any unwanted parsing:

    filter=(--include='lib/***' --include='arm-none-eabi/include/***' \
      --include='arm-none-eabi/lib/***' --include='*/' --exclude='*')
    rsync -amnv "${filter[@]}" /tmp/from/ /tmp/to/
    

    Note that arrays are available in bash and zsh, but not all other POSIX-compatible shells. Also, I lowercased the filter variable name -- recommended practice to avoid colliding with the shell's special variables (which are all uppercase).

    0 讨论(0)
提交回复
热议问题