Expect 脚本:创建使用 ssh 登录远程服务器的方法,并在方法返回后发送命令
Expect script: Create method to login to a remote server using ssh and send commands after method has returned
我一直在尝试编写一个 expect 脚本,它有一个打开 ssh 连接的方法,这个方法可以被其他方法调用,以便它们可以发送额外的命令来执行。我已经拥有的是 -
#!/usr/bin/expect
set timeout -1
#log_user 0
set username [lindex ${argv} 0]
set node_address [lindex ${argv} 1]
set password [lindex ${argv} 2]
set prompt ".*\[>#:$%\] \?$"
set password_prompt ".*: \?$"
set install_dir "/usr/share/elasticsearch"
set conf_dir "/etc/elasticsearch"
set plugin_manager "${install_dir}/bin/elasticsearch-plugin"
set es_config_file "${conf_dir}/elasticsearch.yml"
puts "Attempting login to ${node_address}"
spawn ssh ${username}@${node_address}
expect -re ${password_prompt} {send -- "${password}\n"}
expect -re ${prompt} {send -- "sudo su - kompuser\n"}
expect -re ${prompt}
puts "Logged in to the node ${node_address} successfully"}
expect -re ${prompt}
send -- "curl -XGET 'localhost:9200/_cat/nodes?v&h=ip,node.role'\n"
expect -re ${prompt}
send_user $expect_out(buffer)
我有其他脚本尝试使用类似的代码登录主机,但有很多代码重复。我想通过编写一个方法来避免代码重复,让我们称之为 login
并在向远程服务器发送任何命令之前调用它,我想要的是 -
#!/usr/bin/expect
set timeout -1
#log_user 0
set username [lindex ${argv} 0]
set node_address [lindex ${argv} 1]
set password [lindex ${argv} 2]
set prompt ".*\[>#:$%\] \?$"
set password_prompt ".*: \?$"
set install_dir "/usr/share/elasticsearch"
set conf_dir "/etc/elasticsearch"
set plugin_manager "${install_dir}/bin/elasticsearch-plugin"
set es_config_file "${conf_dir}/elasticsearch.yml"
proc login {username node_address password prompt password_prompt} {
puts "Attempting login to ${node_address}"
spawn ssh ${username}@${node_address}
expect -re ${password_prompt} {send -- "${password}\n"}
expect -re ${prompt} {send -- "sudo su - kompuser\n"}
puts "Logged in to the node ${node_address} successfully"}
proc get_node_info {username node_address password prompt password_prompt} {
login ${username} ${node_address} ${password} ${prompt} ${password_prompt}
expect -re ${prompt}
send -- "curl -XGET 'localhost:9200/_cat/nodes?v&h=ip,node.role'\n"
expect -re ${prompt}}
proc restart_node {username node_address password prompt password_prompt} {
login ${username} ${node_address} ${password} ${prompt} ${password_prompt}
expect -re ${prompt} {send -- "sudo systemctl daemon-reload\n"}
expect -re ${prompt} {send -- "sudo systemctl start elasticsearch.service\n"}
expect -re ${prompt}
}
get_node_info ${username} ${node_address} ${password} ${prompt} ${password_prompt}
restart_node ${username} ${node_address} ${password} ${prompt} ${password_prompt}
问题是对登录的调用成功登录,但期待调用者的提示挂起 -
以下是启用调试日志的日志的最后几行 -
send: sending "sudo su - kompuser\n" to { exp4 }
Logged in to the node 10.109.14.73 successfully
Gate keeper glob pattern for '.*[>#:$%] ?$' is ''. Not usable, disabling the performance booster.
expect: does "" (spawn_id exp0) match regular expression ".*[>#:$%] ?$"? (No Gate, RE only) gate=yes re=no
任何帮助将不胜感激。
谢谢
当您 运行 spawn
在 proc 中时,变量 spawn_id
在当前堆栈帧中创建,除非采取特殊措施,否则使其成为局部变量。
有了这些知识,解决方案就很简单了:在 运行 执行 spawn
命令之前将 spawn_id
声明为全局变量:
proc login {username node_address password prompt password_prompt} {
global spawn_id
puts "Attempting login to ${node_address}"
spawn ssh ${username}@${node_address}
expect -re ${password_prompt} {send -- "${password}\n"}
expect -re ${prompt} {send -- "sudo su - kompuser\n"}
puts "Logged in to the node ${node_address} successfully"
}
我相信你不需要在其他过程中这样做。但为了保持一致性,我会。
我一直在尝试编写一个 expect 脚本,它有一个打开 ssh 连接的方法,这个方法可以被其他方法调用,以便它们可以发送额外的命令来执行。我已经拥有的是 -
#!/usr/bin/expect
set timeout -1
#log_user 0
set username [lindex ${argv} 0]
set node_address [lindex ${argv} 1]
set password [lindex ${argv} 2]
set prompt ".*\[>#:$%\] \?$"
set password_prompt ".*: \?$"
set install_dir "/usr/share/elasticsearch"
set conf_dir "/etc/elasticsearch"
set plugin_manager "${install_dir}/bin/elasticsearch-plugin"
set es_config_file "${conf_dir}/elasticsearch.yml"
puts "Attempting login to ${node_address}"
spawn ssh ${username}@${node_address}
expect -re ${password_prompt} {send -- "${password}\n"}
expect -re ${prompt} {send -- "sudo su - kompuser\n"}
expect -re ${prompt}
puts "Logged in to the node ${node_address} successfully"}
expect -re ${prompt}
send -- "curl -XGET 'localhost:9200/_cat/nodes?v&h=ip,node.role'\n"
expect -re ${prompt}
send_user $expect_out(buffer)
我有其他脚本尝试使用类似的代码登录主机,但有很多代码重复。我想通过编写一个方法来避免代码重复,让我们称之为 login
并在向远程服务器发送任何命令之前调用它,我想要的是 -
#!/usr/bin/expect
set timeout -1
#log_user 0
set username [lindex ${argv} 0]
set node_address [lindex ${argv} 1]
set password [lindex ${argv} 2]
set prompt ".*\[>#:$%\] \?$"
set password_prompt ".*: \?$"
set install_dir "/usr/share/elasticsearch"
set conf_dir "/etc/elasticsearch"
set plugin_manager "${install_dir}/bin/elasticsearch-plugin"
set es_config_file "${conf_dir}/elasticsearch.yml"
proc login {username node_address password prompt password_prompt} {
puts "Attempting login to ${node_address}"
spawn ssh ${username}@${node_address}
expect -re ${password_prompt} {send -- "${password}\n"}
expect -re ${prompt} {send -- "sudo su - kompuser\n"}
puts "Logged in to the node ${node_address} successfully"}
proc get_node_info {username node_address password prompt password_prompt} {
login ${username} ${node_address} ${password} ${prompt} ${password_prompt}
expect -re ${prompt}
send -- "curl -XGET 'localhost:9200/_cat/nodes?v&h=ip,node.role'\n"
expect -re ${prompt}}
proc restart_node {username node_address password prompt password_prompt} {
login ${username} ${node_address} ${password} ${prompt} ${password_prompt}
expect -re ${prompt} {send -- "sudo systemctl daemon-reload\n"}
expect -re ${prompt} {send -- "sudo systemctl start elasticsearch.service\n"}
expect -re ${prompt}
}
get_node_info ${username} ${node_address} ${password} ${prompt} ${password_prompt}
restart_node ${username} ${node_address} ${password} ${prompt} ${password_prompt}
问题是对登录的调用成功登录,但期待调用者的提示挂起 - 以下是启用调试日志的日志的最后几行 -
send: sending "sudo su - kompuser\n" to { exp4 }
Logged in to the node 10.109.14.73 successfully
Gate keeper glob pattern for '.*[>#:$%] ?$' is ''. Not usable, disabling the performance booster.
expect: does "" (spawn_id exp0) match regular expression ".*[>#:$%] ?$"? (No Gate, RE only) gate=yes re=no
任何帮助将不胜感激。 谢谢
当您 运行 spawn
在 proc 中时,变量 spawn_id
在当前堆栈帧中创建,除非采取特殊措施,否则使其成为局部变量。
有了这些知识,解决方案就很简单了:在 运行 执行 spawn
命令之前将 spawn_id
声明为全局变量:
proc login {username node_address password prompt password_prompt} {
global spawn_id
puts "Attempting login to ${node_address}"
spawn ssh ${username}@${node_address}
expect -re ${password_prompt} {send -- "${password}\n"}
expect -re ${prompt} {send -- "sudo su - kompuser\n"}
puts "Logged in to the node ${node_address} successfully"
}
我相信你不需要在其他过程中这样做。但为了保持一致性,我会。