Sebastian Luhnburg wrote on Thu, Jun 29, 2023 at 11:55:12AM +0200: > initial_password="\$abc&xyz" > echo "initial password: " $initial_password > printf -v password '%q' $initial_password > echo "initial password with escaped characters: " $password > bash << EOF > echo "password in here document: " ${password@Q} > /bin/bash -c "echo 'password in subshell in here document: ' ${password@Q}"
password here is \$abc\&xyz, and the @Q escape just makes ${password@Q} '\$abc\&xyz' (adds single quotes). What running it in a subshell (ssh, or sh/bash -c) changes here is the order in which things are unescaped. Note the here-doc substitutes ${password@Q}, so this is the same as running a file with the content: ``` echo "password in here document: " '\$abc\&xyz' /bin/bash -c "echo 'password in subshell in here document: ' '\$abc\&xyz'" ``` Like this, you can see that in the former case, the echo command gets the password in single quotes, while the subshell's echo is first interpreted in double-quotess. In double-quotes, \$ is simplified to $ (as the lack of backslash would just get you the variable) Note that since the here-doc first expands the variable, you cannot solve this by using single quotes: the variable would just end the quoting! ... At which point all you need to do is just to open the quote, e.g. the following: a='$foo&bar' b="${a@Q}" c="${b@Q}" ssh localhost <<EOF ssh localhost "echo "$c EOF prints: $foo&bar I'd still recommend avoiding embedding ssh in another ssh in a script though... -- Dominique Martinet | Asmadeus