How are strings with multiple kinds of quotes interpreted in bash?

To give context, I’m trying to create a simple version of bash, and for that I need to mimic the way bash parses content with multiple sets of single and double quotes. I can’t figure out the overall procedure by which bash handles quotes inside quotes. I noticed some repeated patterns but still don’t have the full picture.

For instance this example:

$ "'"ls"'"

evaluates to:

$ 'ls'

or even this uglier example:

$ "'"'"""'"ls"'"""'"'"

evaluates to:

$ '"""ls"""'

I noticed the following patterns arise:

  • if count of wrapping quotes are even it evaluates to what’s inside the inverse quotes exclusively
  • if count of wrapping quotes are odd it evaluates to what’s inside the inverse quotes inclusively.

For example even wrapping quotes:

$ ""'ls'""

evaluates to what’s inside the inverse quotes (single quotes) without the single quotes themselves, evaluation:

$ ls

Or for odd count of wrapper quotes:

$ '''"ls"'''

it evaluates to content of double quotes inclusively:

$ "ls" : command not found.

Still I don’t get the full picture of how this parsing pattern for more complex quotes inside quotes is done.

>Solution :

Quotes are processed sequentially, looking for matching closing quotes. Everything between the starting and ending quote becomes a single string. Nested quotes have no special meaning.

"'"ls"'"

When it processes the first ", it scans looking for the next " that ends the string, which contains '.

Then it scans the fixed string ls.

When it processes the " after ls, it scans looking for the next ", resulting in another string '.

These are all concatenated, resulting in 'ls'.

"'"'"""'"ls"'"""'"'"

"'" is the string '.

'"""' is the string """

"ls" is the string ls

'"""' is the string """

"'" is the string '.

Concatenating them all together produces '"""ls"""'

""'ls'""

"" is an empty string. 'ls' is the string ls. "" is another empty string. Concatenating them together produces ls.

'''"ls"'''

'' is an empty string. '"ls"' is the string "ls" (containing literal double quotes). '' is an empty string. Concatenating them produces "ls". Since there’s no command with that name (including the literal double quotes), you get an error.

There are differences between single and double quotes, but they don’t affect any of the examples you posted. See Difference between single and double quotes in Bash

Leave a Reply