Escape a string for bash, zsh, sh, PowerShell, cmd.exe and fish

Quote one string or a list of arguments for five shells, and see how each shell splits the result, so you know it reads back unchanged.

How it works

  1. Type or paste the text, or switch to Argument list and give one argument per line
  2. Pick the cmd.exe percent style and the optional $'...' form for bash and zsh
  3. Copy the line for your shell and check the table that shows how it is split

Single quotes for bash, zsh, sh and fish

To escape a string for bash or zsh, wrap it in single quotes and write every single quote inside it as '\'' , which closes the quote, adds an escaped quote and opens the quote again. Worked example: It's becomes 'It'\''s'. Inside single quotes the shell performs no expansion, so $HOME, a backtick, * and & stay as typed. Plain words made only of letters, digits and _ @ % + = : , . / - are left unquoted, except a word that starts with = or %. In an argument list the first item is the command, so a first item that the shell reads as syntax (if, while, for and the like) or as an assignment (FOO=bar) is quoted too; fish reports Not possible for its syntax words. The empty string becomes ''. POSIX sh uses the same form. fish also uses single quotes, but inside them a backslash and a single quote are the escapes, so It's becomes 'It\'s' and a backslash becomes two. The option for bash and zsh writes text with a line break or tab as $'a\nb'; POSIX sh has no such form.

PowerShell

PowerShell treats a single-quoted string as verbatim, and a single quote inside it is written twice, so It's becomes 'It''s'. PowerShell also reads the typographic quotes U+2018, U+2019, U+201A and U+201B as single quotes, so this tool doubles those too. A word that starts with a dash, such as -Force, is quoted so that it reads as text and not as a parameter name. In an argument list the first item is the command. A quoted string in that place is only a string, so a program path with a space is written & 'C:\Program Files\app.exe' with the call operator, and a keyword such as if is written the same way. These command rules come from Microsoft's about_Parsing page and are not run in a real PowerShell by this tool. PowerShell removes the outer quotes before a program receives the argument, and Microsoft documents extra care for arguments that contain double quotes or go to batch files; see its about_Parsing page for those cases.

cmd.exe

cmd.exe needs two steps. First the argument is quoted for the program that will read the command line, the rule Microsoft documents for the C runtime and CommandLineToArgvW: wrap it in double quotes, write a double quote inside as backslash and quote, and double any backslashes in front of a quote or at the end. Then every cmd metacharacter, which means ( ) % ! ^ " < > & and |, gets a caret in front, including the double quotes. For example, hello world becomes ^"hello world^", and 50% off in a batch file becomes ^"50%% off^". A line break cannot go through cmd.exe at all, because it ends the command; the tool says so instead of guessing. In an argument list the first item is the program name, which both parsers read without any backslash rule, so it is quoted separately and shown unchanged; cmd.exe also reads if, for, rem and goto, or a word starting with @ or a colon, as syntax, and the tool says Not possible for those. At the prompt, a name between two percent signs is replaced when a variable of that name exists, and the tool cannot know your variables, so text like %PATH% is marked Not checked there; choose the .bat file option, where a percent sign is written %%.

The check, and what quoting does not cover

Each result is split again by a small reader written for that shell, and the table shows the words it found and whether they equal your input. That proves the quoting round-trips; it does not run any shell. An argument list is read one per line, or from a JSON array such as ["git","commit","-m","a b"], which is the way to pass an empty argument. A NUL character cannot be part of an argument, and input is limited to 100,000 characters and 1,000 arguments. Quoting protects one level of shell. If the command goes through ssh, bash -c, sudo or docker exec, a second shell reads the text and it needs a second round of quoting.

Frequently asked questions

How do I escape a single quote inside single quotes in bash?

You cannot put one inside, so close the quote, add an escaped quote and reopen: 'It'\''s' reads back as It's. In POSIX, single quotes keep every character literal, and a single quote cannot appear between them. The tool does this rewrite for you.

How do I escape a single quote in PowerShell?

Write it twice inside a single-quoted string: 'It''s' gives It's. The same applies to the curly quotes U+2018 and U+2019, which PowerShell also treats as quote marks, so a pasted ‘word’ must be doubled as well.

Why does my path with a trailing backslash break in cmd.exe?

For an argument, a backslash right before a closing double quote is read as an escape. As an argument, C:\a b\ must be written "C:\a b\\" so the quote still closes, and then each metacharacter gets a caret. The tool applies both steps and shows the words it reads back. The program name, the first item of an argument list, has no such rule: its backslashes are literal and it is quoted without doubling them.

How do I turn an argv array into a command line?

Choose Argument list and give one argument per line, or a JSON array such as ["git","commit","-m","fix: a b"]. Each argument is quoted on its own and joined with spaces, so the bash line is git commit -m 'fix: a b'. Use JSON when one argument is empty.

Do I still need quoting if the command runs through ssh or bash -c?

Yes, twice. The local shell reads the line first, and then the remote shell or the bash -c string is read again. Quote the text for the inner shell first, then quote that whole result for the outer one by running it through this tool a second time.

Is my text uploaded?

No. It is processed in your browser, in this tab, and no server receives it. Your mode, the $'...' choice and the cmd.exe percent style are saved in this browser, the text is not.