Shell Script, KM Variable & Quoting

Here's the command I'm trying to run:

zip -rj "$KMVAR_FTP__UploadArchive".zip "$KMVAR_FTP__FilesToCopy"

The "FTP__FilesToCopy" variable is:

'/Users/test/Desktop/untitled folder/01.wav' '/Users/test/Desktop/untitled folder/02.wav' '/Users/test/Desktop/untitled folder/03.wav' '/Users/test/Desktop/untitled folder/04.wav' '/Users/test/Desktop/untitled folder/05.wav'

Each file path is enclosed in single quotes and there is a space between each path.

This works fine if I just run this command:

zip -rj "$KMVAR_FTP__UploadArchive".zip '/Users/test/Desktop/untitled folder/01.wav' '/Users/test/Desktop/untitled folder/02.wav' '/Users/test/Desktop/untitled folder/03.wav' '/Users/test/Desktop/untitled folder/04.wav' '/Users/test/Desktop/untitled folder/05.wav'

But it is not working when trying to use the $KMVAR. I'm assuming it is related to the quotes as described here:

I can't wrap my head around this one. The zip command wants the individual files separated by a space and the reason they are single quoted is because of the spaces in the path. But the KMVAR is double quoted so obviously the zip command is not actually seeing the individual file paths.

Any help is much appreciated!

Thanks

The first problem you are going to have with this is that the shell processes quotes before variable interpolation, not after - a variable can never contain meaningful quotes (at least not unless you are going to do later processing).

So your handling of

"$KMVAR_FTP__UploadArchive".zip 

is correct - The FTP__UploadArchive variable contains the path to the file, and should not have any quotes or any backslashes, and can have spaces.

However there is no way to have quotes or quoted spaces within a variable and also have the variable contain a list of paths when you use it in a script like that. Your only options are:

  • $KMVAR_FTP__FilesToCopy - quotes are treated as characters, the arguments will be split by spaces.
  • "$KMVAR_FTP__FilesToCopy" - quotes and spaces are treated as characters (one single argument).
  • '$KMVAR_FTP__FilesToCopy' - the text $KMVAR_FTP__FilesToCopy verbatim as a single argument.

None of these are what you want.

The solution to this is to use the xargs tool.

Create your FTP__FilesToCopy, do not use any quotes or blackslashes, and separate the files with returns, so it should be something like:

/Users/test/Desktop/untitled folder/01.wav
/Users/test/Desktop/untitled folder/02.wav
…
/Users/test/Desktop/untitled folder/05.wav

Then run the command:

tr '\n' '\0' | xargs -t -0 -J HERE zip -rj "$KMVAR_FTP__UploadArchive".zip HERE

with input from the FTP__FilesToCopy variable. Or probably this would work too:

echo "$KMVAR_FTP__FilesToCopy" | tr '\n' '\0' | xargs -t -0 -J HERE zip -rj "$KMVAR_FTP__UploadArchive".zip HERE

The wiki describes this process at the end of the Quoting Strings section.

3 Likes

Peter, as always, thank you for you input!

This worked perfectly.

I had a suspicion that this simply wasn't possible with the usual syntax.

1 Like