【问题标题】:Expect commands on SSH going out of sync期望 SSH 上的命令不同步
【发布时间】:2015-05-12 07:56:25
【问题描述】:

我创建了一个脚本,我需要在其中使用 SSH 在远程终端上运行一些命令。所以我使用了期望语句,但问题是,假设我必须在远程终端上运行 5 个语句,然后在 6 次中,大约 3-4 次,这 5 个命令不同步,即命令没有以正确的顺序执行,并且方式不正确,即首先第一个命令应该完成,然后第二个应该运行。 我试图设置超时 5 甚至 10,但它没有帮助。我什至尝试了睡眠 2 或 4,但它也没有帮助。这是我与输出一起创建的脚本。请帮我。谢谢。

脚本:

do some work on current shell
#echo $name 
## ssh part of script starts

/usr/bin/expect<<EXEOF

set timeout -1
match_max 100000
spawn ssh "myuser\@IP_ADDRESS"
expect "*assword:*"
send -- "mypassword\r"
send -- "\r"
#expect -re "(%|*>|#|\\$)"
expect "*>"
#expect "*OFR:offline-ure>"   #actual prompt of ssh terminal
send -- "\r"
set timeout 20
#sleep 1
send -- "tcsh\r"
send -- "\r"
set timeout 2
expect -re "(%|>|#|\\$)"
#set timeout 10
send -- "cd /home/myuser/cap/\r"
send -- "\r"
set timeout 4
expect -re "(%|>|#|\\$)"
send -- "source cap.env\r"
send -- "\r"
set timeout 10
send -- "cd /home/myuser/bin/\r"
set timeout 5
expect -re "(%|>|#|\\$)"
send -- "$myCommand\r"
#set timeout 50
#sleep 40
send -- "exit\r"
expect -re "(%|>|#|\\$)"
send -- "exit\r"
expect eof

EXEOF
echo "end of ssh script"
some task after ssh part of script

当我运行它时,我看到以下输出:

spawn ssh myuser@IP_ADDRESS
myuser@XX.XX.XX.XXX's password:
Last login: Tue Mar 10 07:56:19 2015 from XX.XX.XX.XX

OFR:offline-ure> tcsh   (see here all commands are sent together)

source ccap.env

cd /home/myuser/bin/
mycommand_String_value
exit
exit
[sncpuser@offline-ure ~]$
[sncpuser@offline-ure ~]$ source ccap.env
ccap.env: No such file or directory.
[sncpuser@offline-ure ~]$
[sncpuser@offline-ure ~]$ cd /home/myuser/bin/
[sncpuser@offline-ure bin]$ mycommand_string_value
some output of my command
[sncpuser@offline-ure bin]$ exit
exit
OFR:offline-ure>
OFR:offline-ure> cd /home/myuser/cap/     (this was second command)
OFR:offline-ure> exit
Connection to xx.xx.xx.xxx closed.
end of ssh script

请注意,在输出中,我需要在 SSH 终端上执行的所有命令都是同时发送的,因此无法按正确的顺序正确运行。 请建议我该如何解决这个问题。提前致谢。

【问题讨论】:

  • exp_internal 1 添加到期望脚本的顶部,当期望模式不匹配(或意外匹配)时,expect 会告诉您

标签: unix ssh expect


【解决方案1】:

这对评论来说太长了,否则它会是一个,但你似乎让自己的生活变得困难。 expect 脚本很容易出错,因此您希望尽可能减少它们。

为什么不:

ssh foo ". /home/myusr/cap/env ; /home/myusr/cap/bin/cmd"

然后只用expect 做用户名/密码位?

或者更好,使用公钥认证,根本不做用户名/密码,完全放弃expect

您在 cmets 中询问如何将多个命令传递给 ssh。试试这个:

amb@nimrod-ubuntu:~/so$ ssh 192.200.0.1 'pwd ; ls | wc -l ; cd .. ; pwd ; ls | wc -l'
amb@192.200.0.1's password:
/home/amb
132
/home
2

ssh 默认使用你的登录 shell。如果你真的需要使用 tcsh 而这不是你的登录 shell,这里有一种方法:

ssh 192.200.0.1 '/bin/sh -c "pwd ; ls | wc -l ; cd .. ; pwd ; ls | wc -l"'

另一种方法是将脚本文件放在远程系统上,例如在/home/myuser/cap/bin/dostuff 写:

#!/bin/tcsh
cd /home/myuser/cap/
source cap.env
cd /home/myuser/bin/
# next line will run the file given as the first parameter
$1
exit

然后调用它:

ssh 192.200.0.1 /home/myuser/cap/bin/dostuff /path/to/file/to/run

我怀疑实际问题与伪终端的分配有关。您可能想使用-t-T 选项来玩ssh

【讨论】:

  • 感谢 abligh 这么快的回复。我对这些东西有点陌生,但我需要使用用户名/密码。如何使用: ssh foo "./home/myusr/cap/env ; /home/myusr/cap/bin/cmd" 意味着一旦我完成了 SSH,我需要依次执行大约 5 个命令。那么如何使用您建议的代码。你能在这里多帮忙吗。我不知道如何仅将期望用于用户名/密码,然后正常运行命令或远程终端....
猜你喜欢
  • 2015-06-27
  • 1970-01-01
  • 2017-06-11
  • 2013-04-19
  • 1970-01-01
  • 2017-05-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多