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