Search code examples
bashparameter-expansion

Is this some kind of regex within bash variable instantiation?


What do those two assignations (i and C omitting the first one to void) do? Is it some kind of regex for the variable? I tried with bash, but so far there were no changes in the output of my strings after instantiating them with "${i//\\/\\\\}" or "\"${i//\"/\\\"}\""

C=''
for i in "$@"; do
    i="${i//\\/\\\\}"
    C="$C \"${i//\"/\\\"}\""
done

Solution

  • ${i//\\/\\\\} is a slightly complicated-looking parameter expansion:

    It expands the variable $i in the following way:

    • ${i//find/replace} means replace all instances of "find" with "replace". In this case, the thing to find is \, which itself needs escaping with another \.
    • The replacement is two \, which each need escaping.

    For example:

    $ i='a\b\c'
    $ echo "${i//\\/\\\\}"
    a\\b\\c
    

    The next line performs another parameter expansion:

    • find " (which needs to be escaped, since it is inside a double-quoted string)
    • replace with \" (both the double quote and the backslash need to be escaped).

    It looks like the intention of the loop is to build a string C, attempting to safely quote/escape the arguments passed to the script. This type of approach is generally error-prone, and it would probably be better to work with the input array directly. For example, the arguments passed to the script can be safely passed to another command like:

    cmd "$@" # does "the right thing" (quotes each argument correctly)
    

    if you really need to escape the backslashes, you can do that too:

    cmd "${@//\\/\\\\}" # replaces all \ with \\ in each argument