6

I want to write a function in bash that forwards arguments to cp command. For example: for the input

<function> "path/with whitespace/file1" "path/with whitespace/file2" "target path"

I want it to actually do:

cp "path/with whitespace/file1" "path/with whitespace/file2" "target path"

But instead, right now I'm achieving:

cp path/with whitespace/file1 path/with whitespace/file2 target path

The method I tried to use is to store all the arguments in an array, and then just run the cp command together with the array. Like this:

function func {
    argumentsArray=( "$@" )
    cp ${argumentsArray[@]}
}

unfortunately, It doesn't transfer the quotes like I already mentioned, and therefore the copy fails.

Alex Weitz
  • 3,199
  • 4
  • 34
  • 57
  • See also [When to wrap quotes around a shell variable?](http://stackoverflow.com/questions/10067266/when-to-wrap-quotes-around-a-shell-variable) – tripleee Mar 18 '17 at 10:58

1 Answers1

5

Just like $@, you need to quote the array expansion.

func () {
    argumentsArray=( "$@" )
    cp "${argumentsArray[@]}"
}

However, the array serves no purpose here; you can use $@ directly:

func () {
    cp "$@"
}
chepner
  • 497,756
  • 71
  • 530
  • 681
  • Thanks! It works when doing `func "the file.txt" /tmp`, however it shows an error when trying to use `func "*.txt" /tmp`. The reason is understood ("shell expansion", etc.), but... does a solution exist? – Ganton Aug 19 '19 at 17:09
  • Not a good one. I recommend writing `func` to you can call it as `func /tmp *.txt`, so that you can use `shift` to remove `/tmp` from the list of positional arguments and use `"$@"` to access the remaining arguments (which came from `*.txt`). – chepner Aug 19 '19 at 17:39