Bash – Filenames with spaces in backtick substitution

bashcommand-substitutionquotingshell

Suppose I have a file containing a space in its name such as with space. What should cmd output in the below snippet for ls to accept 'with space' as argument?

$ ls `cmd`

I tried ls `echo 'with space'`. The arguments passed to ls are 'with and space'. Trying to escape the space using backslash doesn't work either. I see that using ls "`cmd`" works. But, this does not work if I want to pass multiple files as argument to ls with some possibly containing spaces.

The manual on command substitution also appears sparse. https://www.gnu.org/software/bash/manual/html_node/Command-Substitution.html

More generally, what is the output format to be followed by cmd if it wants to output a list of files which can then substituted to be used by another command using backtick substitution?

Best Answer

I see that using ls "`cmd`" works. But, this does not work if I want to pass multiple files as argument to ls with some possibly containing spaces.

That's correct. It's the same issue as with storing commands in a variable (discussed e.g. here), it can't really be done nicely. The options that come to mind are:

  • Have cmd output a NUL-separated list of filenames, then pipe to xargs -0 to pass them to another command
  • Set IFS to some character that doesn't appear in any filenames, and have cmd output the list of files separated by that
  • Have cmd output the file names properly quoted for the shell, and then run it through eval.

Like so:

$ touch "with space" "another space"
$ printf "%s\0" "with space" "another space" | xargs -0 ls -i
1705749 another space  1705230 with space
$ set -f; IFS=%; ls -i $(echo "with space%another space")
1705749 another space  1705230 with space
$ eval ls -i "$(echo '"with space" "another space"')"
1705749 another space  1705230 with space

Or use find -exec ... if you can replace cmd with that.