bash 中用于预期块的特殊字符密码变量不起作用

bash 中用于预期块的特殊字符密码变量不起作用

我已经为这个问题苦苦挣扎了好几天了。我在网上搜索解决方案,尝试了许多不同的方法,但到目前为止似乎都没有成果。我传递了一个包含特殊字符的密码变量来阻止它,但它总是在密码处出错。

这是我的脚本:

#!/usr/bin/bash
server_List=("MySQLServer1" "MySQLServer2")
osUser='mysql'
osUserPwd='H3htg#41fRth!'
newRootPass='prnH4xRJSMwbWn9ht!M5t'
oldRootPwd='prnH4x^JSMwbWn9h!M6J'
    for host in ${server_List[@]}
      do
        echo "Processing host $host"
        /usr/bin/expect -c '
        spawn ssh -o "StrictHostKeyChecking no" '$osUser'@'$host';
        expect "password: "
        send "'$osUserPwd'\r"
        expect "$ "
        send -- "mysqladmin --user root -p password '$newRootPass'"
        expect "Enter password: "
        send -- "'$oldRootPwd'\r"
        expect "$ "
        send "exit\r" '
    done

错误如下:

[mysql@centralserver myself]$ ./test2.sh
Processing host MySQLServer1
spawn ssh -o StrictHostKeyChecking no mysql@MySQLServer1
Password:
Last login: Tue Jan 24 10:00:43 2023 from 10.14.20.18
[mysql@MySQLServer1 ~]$ mysqladmin --user root -p password prnH4xRJSMwbWn9ht!M5tprnH4x^JSMwbWn9h!M6J
-bash: !M5tprnH4x: event not found

如果有人能指出我哪里犯了错误我将非常感激。

答案1

你的所有 shell 变量未引用在 shell 中。这允许 shell 执行各种替换

代替

send "'$osUserPwd'\r"

你必须做

send "'"$osUserPwd"'\r"
# .....^..........^

或者,不要将期望代码逐个编写为字符串,而是通过环境传递 shell 变量:

#!/usr/bin/bash
server_List=("MySQLServer1" "MySQLServer2")
osUser='mysql'
osUserPwd='***'
newRootPass='***'
oldRootPwd='***'
export osUser osUserPwd newRootPass oldRootPwd host

for host in "${server_List[@]}"     # <= quoted
do
    echo "Processing host $host"
    /usr/bin/expect << 'END_EXPECT'   # a quoted heredoc
        spawn ssh -o "StrictHostKeyChecking no" $env(osUser)@$env(host)
        expect "password: "
        send "$env(osUserPwd)\r"
        expect "$ "

        # Need to send literal quotes for the password on the mysqladmin
        # command below: this prevents the remote shell from altering
        # the password on the command line.
        # Don't forget \r to hit enter.
        send -- "mysqladmin --user root -p password '$env(newRootPass)'\r"
        expect "Enter password: "
        send -- "$env(oldRootPwd)\r"
        expect "$ "
        send "exit\r"
        expect eof     # <= gracefully wait for the ssh connection to end
END_EXPECT
done

相关内容