使用 BASH 和 Expect 进行远程 SSH 和命令执行
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11227648/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Remote SSH and command execution using BASH and Expect
提问by Tamas
I'm trying to achieve the following with a bash script:
我正在尝试使用 bash 脚本实现以下目标:
- try for SSH connection, if fails, error out if SSH connection is
- once confirmed, execute the 'top' command and save results to file
- scp file back from remote server
- 尝试 SSH 连接,如果失败,如果 SSH 连接是错误的
- 确认后,执行“top”命令并将结果保存到文件
- 从远程服务器返回 scp 文件
I know the invidiual commands, which would be: 1) to check the ssh connection:
我知道单独的命令,这将是:1)检查 ssh 连接:
ssh -q user@ip exit
echo $?
echo $?
This should return '0' on success and '255' on error.
这应该在成功时返回“0”,在错误时返回“255”。
2) to execute top and save to file would be:
2)执行top并保存到文件将是:
top -n 1 -b > /tmp/top.out
3) scp back file from remote host
3) 来自远程主机的 scp 备份文件
expect -c "
set timeout 1
spawn scp user@host:/tmp/top.out root@anotherhost:/.
expect yes/no { send yes\r ; exp_continue }
expect password: { send password\r }
expect 100%
sleep 1
exit
"
Now putting this altogether is my problem, to be more specific:
现在把这完全是我的问题,更具体地说:
I can't seem to be able to get the returned '0' and '255' values when using expect to test the SCP connection.
- I can't seem to be able to execute the top command using expect again, i.e. this doesn't work:
expect -c " set timeout 1 spawn ssh user@host top -n 3 -b > /tmp/top.out expect password: { send password\r } sleep 1 exit "
- and therefore the 3rd bit won't work either.
使用expect测试SCP连接时,我似乎无法获得返回的“0”和“255”值。
- 我似乎无法再次使用 expect 执行 top 命令,即这不起作用:
期望 -c “设置超时 1 spawn ssh user@host top -n 3 -b > /tmp/top.out 期望密码:{ 发送密码\r } 睡眠 1 退出”
- 因此第三位也不起作用。
Any help is appreciated. Please bear in mind that my script is a .sh script with the #!/bin/bashdeclaration -- I cannot use #!/usr/bin/expectfor various reasons.
任何帮助表示赞赏。请记住,我的脚本是带有#!/bin/bash声明的 .sh 脚本——由于各种原因我不能使用#!/usr/bin/expect。
回答by Jo So
Now that's ugly stuff. There are many pitfalls, probably you are not quite sure at what places you execute with a shell, or with plain argv array. Also the expect stuff is not the way thatis supposed to be done, that's only brittle.
现在这是丑陋的东西。有很多陷阱,可能您不太确定使用 shell 或纯 argv 数组在哪些地方执行。另外,期望的东西是不一样那是应该做的,这只是脆。
(AFAIK, expectis mainly meant to be used to communicate with modems (AT command set) and the like).
(AFAIK,expect主要用于与调制解调器(AT 命令集)等通信)。
Use SSH keys for automated ssh and scp instead of passwords. Once you've done that (or even before, but then you have to enter passwords manually), launch this in your shell:
使用 SSH 密钥进行自动 ssh 和 scp,而不是密码。一旦你这样做了(甚至之前,但你必须手动输入密码),在你的 shell 中启动它:
$ ssh user@server "top -n 1 -b" > /tmp/top.out
and the file will be on your localmachine. (Because redirection was done locally, not yet remotely). No need to scp.
并且该文件将在您的本地计算机上。(因为重定向是在本地完成的,而不是远程完成的)。不需要scp。
That's all there is to it.
这里的所有都是它的。
回答by Samuel
Check this one: https://stackoverflow.com/a/23632210/524743
检查这个:https: //stackoverflow.com/a/23632210/524743
expect <<'END'
log_user 0
spawn sh -c {echo hello; exit 42}
expect eof
puts $expect_out(buffer)
lassign [wait] pid spawnid os_error_flag value
if {$os_error_flag == 0} {
puts "exit status: $value"
} else {
puts "errno: $value"
}
END
hello
exit status: 42
From the expect man page
从期望手册页
wait [args]
delays until a spawned process (or the current process if none is named) terminates.
wait normally returns a list of four integers. The first integer is the pid of the process that was waited upon. The second integer is the corresponding spawn id. The third integer is -1 if an operating system error occurred, or 0 otherwise. If the third integer was 0, the fourth integer is the status returned by the spawned process. If the third integer was -1, the fourth integer is the value of errno set by the operating system. The global variable errorCode is also set.
等待 [参数]
延迟直到产生的进程(或当前进程,如果没有命名)终止。
wait 通常返回一个包含四个整数的列表。第一个整数是等待的进程的 pid。第二个整数是对应的 spawn id。如果发生操作系统错误,则第三个整数为 -1,否则为 0。如果第三个整数为 0,则第四个整数是派生进程返回的状态。如果第三个整数是-1,那么第四个整数就是操作系统设置的errno的值。还设置了全局变量 errorCode。

