How can I escape an arbitrary string for use as a command line argument in Bash? How can I escape an arbitrary string for use as a command line argument in Bash? bash bash

How can I escape an arbitrary string for use as a command line argument in Bash?


If you want to securely quote anything for Bash, you can use its built-in printf %q formatting:

cat strings.txt:

yesnoHello, worldC:\Program Files\"\\\\\\\\\\\\\\\"\"\T"\\T!1!A"!\/'""Jeff's!"$PATH%PATH%&<>|&^*@$$A$@#?-_

cat quote.sh:

#!/bin/bashwhile IFS= read -r stringdo    printf '%q\n' "$string"done < strings.txt

./quote.sh:

yesnoHello\,\ worldC:\\Program\ Files\\\"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"\\\"\\T\"\\\\T\!1\!A\"\!\\/\'\"\"Jeff\'s\!\"\$PATH%PATH%\&\<\>\|\&\^\*@\$\$A\$@#\?-_

These strings can be copied verbatim to for example echo to output the original strings in strings.txt.


What is the general procedure for safely escaping an arbitrary string for use as a command line argument in Bash?

Replace every occurrence of ' with '\'', then put ' at the beginning and end.

Every character except for a single quote can be used verbatim in a single-quote-delimited string. There's no way to put a single quote inside a single-quote-delimited string, but that's easy enough to work around: end the string ('), then add a single quote by using a backslash to escape it (\'), then begin a new string (').

As far as I know, this will always work, with no exceptions.


You can use single quotes to escape strings for Bash. Note however this does not expand variables within quotes as double quotes do. In your example, the following should work:

script.pl '!foo'

From Perl, this depends on the function you are using to spawn the external process. For example, if you use the system function, you can pass arguments as parameters so there"s no need to escape them. Of course you"d still need to escape quotes for Perl:

system("/usr/bin/rm", "-fr", "/tmp/CGI_test", "/var/tmp/CGI");