I'm trying to put a bunch of images together into a pdf. I ran gm convert *.jpg out.pdf and it worked, but the images were not in the right order.I found that ls -v orders them correctly so then I tried gm convert `ls -v *.jpg` out.pdf, but that failed because the files have spaces in the names.So I checked the ls options and tried gm convert `ls -Qv *.jpg` out.pdf and gm convert `ls -bv *.jpg` out.pdf but both failed because, as far as I can tell, the file names got escaped twice (using \ in the first case, and \\ before space in the 2nd case).Why is this happening, and how can I get the file names escaped correctly, i.e. only once? I'm using zsh if that's relevant.
How to prevent double escaping?
shell;filenames;wildcards;quoting;escape characters
You can't use escaping this way. You can use quotes or backslashes for something that understands them like the shell parsing.There's nothing to escape the word splitting done upon variable expansion or command substitution (which is different from the shell parsing (tokenising) of a command line).What you can do is either change the internal field delimiter $IFS to split on newline characters only (but note that except with zsh, you also need to disable filename generation (though not for the expansion of *.jpg obviously) which is the other thing done upon unquoted command substitution, unless you can guarantee that no filename contains globbing characters):set -f # disable filename generationIFS='' # set IFS  to newline characterIFS=$'\n' # alternative for ksh/zsh/bashgm convert $(set +f; ls -v ./*.jpg) out.pdf # you also need ./ in case file                                            # names start with -(that assumes none of the file names contain newline characters)set -f in zsh (unless in sh/ksh emulation) disables reading rc files (think zsh -f, csh -f), which has no effect once the shell is already started so is harmless.With zsh, you can shorten that to:gm convert ${(f)$(ls -v ./*.jpg)} out.pdf(f) short for (ps:\n:) is to split on newline characters.Alternatively, you could use ls quoting to build a shell command line (shell code in shell syntax if you like) to pass to eval which would let the shell evaluate it and run it:With ksh93, zsh or bash:eval images=($(ls --quoting-style=shell -v ./*.jpg))gm convert ${images[@]} out.pdfBut with zsh, you could simply do:gm convert ./*.jpg(n) out.pdf(n) is a globbing qualifier that tells the shell to sort the generated file names numerically.