tmux new-window command plus argument including spaces – bash var

I’m trying to execute a command on a new tmux window. A simple console/terminal pdf reader. The script needs argument, a PDF file, the file name may include spaces. I’ve tried this:


tmux new-window "pdftotext -layout -nopgbrk "${1}" - | less"

It works on files without spaces, eg 1.pdf. I’ve tried sh instead of bash, $1, "$1" instead of "${1}", no effect.

Asked By: Krackout


tmux new-window passes a command to a shell. This is good, your command is a pipeline and you need a shell to process it. But this means there will be a shell that will take your command as a string and only then interpret it (like sh -c does).

It seems tmux new-window (like ssh) can built a command string for the inner (in case of ssh: remote) shell from multiple arguments it gets. For these tools I prefer giving a single argument nevertheless.

You need to quote for that inner shell; at the same time you need to quote for the outer shell that interprets the script. In other words you need to craft the whole tmux command, so after the outer shell substitutes $1 and removes quotes it doesn’t take literally, the string(s) passed to tmux new-window forms a shell command where everything that needs to be quoted is properly quoted for the inner shell.

An obvious idea is to embed some additional quotes. This is flawed though:

# flawed, don't
tmux new-window "pdftotext -layout -nopgbrk "${1}" - | less"
# also flawed, don't
tmux new-window "pdftotext -layout -nopgbrk '${1}' - | less"

An argument containing ", $, `, , ! or ' will break one command and/or the other. Worse, this creates a code injection vulnerability (i.e. for an unfortunate or rogue argument, your script will execute a part of the argument as shell code).

Your script uses Bash. We can ask Bash itself to expand $1 to a quoted form in a safe way. This is done by the Q modifier:

tmux new-window "pdftotext -layout -nopgbrk ${1@Q} - | less"

No matter what $1 expands to, the outer shell will expand ${1@Q} to a form that will look properly quoted to the inner shell.

Answered By: Kamil Maciorowski
Categories: Answers Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.