1

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
Cyrus
  • 84,225
  • 14
  • 89
  • 153
joscabmar
  • 13
  • 3
  • Oof. It looks like an attempt to store a list of DOS file paths in a single string by escaping backslashes and double quotes. A first step would be to simply use an array instead: `C=( "$@" )`. The backslashes should be left alone; if `C` knows about DOS file paths, it doesn't need them to be escaped, and if it doesn't, quoting them probably won't help. – chepner Sep 07 '18 at 13:00

2 Answers2

2

It's bash parameter expansions

  • it replace all backslashes by double backslashes :"${i//\\/\\\\}
  • it replace all \" by \\" : ${i//\"/\\\"}

Check http://wiki.bash-hackers.org/syntax/pe

2

${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
Tom Fenech
  • 72,334
  • 12
  • 107
  • 141