标签: expect

使用expect(1)进行SSH登录.如何退出预期并保留在SSH中?

所以我想自动化我的SSH登录.我所在的主机不允许在此服务器上进行密钥验证,因此我必须更具创造性.

我不太了解shell脚本,但是一些研究向我展示了命令'expect'和一些用于此目的的脚本.我设置了一个脚本并运行它,它完美地登录.

#!/usr/bin/env expect -f

set password "my_password"

match_max 1000

spawn ssh -p 2222 "my_username"@11.22.11.22

expect "*?assword:*"
send -- "$password\r"
send -- "\r"

expect eof
Run Code Online (Sandbox Code Playgroud)

最初,它按预期运行.

Last login: Wed May 12 21:07:52 on ttys002
esther:~ user$ expect expect-test.exp
spawn ssh -p 2222 my_username@11.22.11.22
my_username@11.22.11.22's password: 
Last login: Wed May 12 15:44:43 2010 from 20.10.20.10


-jailshell-3.2$ 
Run Code Online (Sandbox Code Playgroud)

但这就是成功结束的地方.

命令不起作用,但按Enter键只是换行.箭头键和其他非字母数字键产生符号,如'^ [[C','^ [[A','^ [OQ'等[1]

除了最初由expect脚本创建的两个提示外,不会出现其他提示.一旦期望超时,我的本地shell将执行任何被忽略的命令.一个例子:

-jailshell-3.2$ whoami
ls
pwd
hostname
Run Code Online (Sandbox Code Playgroud)

(...时间过去了,期待超时...)

esther:~ user$ whoami
user

esther:~ ciaran$ ls
Books       Documents   Movies      Public      
Code        Downloads …
Run Code Online (Sandbox Code Playgroud)

ssh bash shell expect

8
推荐指数
1
解决办法
3万
查看次数

退出期望{}没有超时

我正在努力解决在ssh中自动输入密码的经典问题,就像其他人一样,我在黑暗中磕磕绊绊地期待着.最后,我拼凑了一个有点工作的脚本:

#!/usr/bin/expect -f

# command line args
set user_at_host [lrange $argv 0 0]
set password [lrange $argv 1 1]

set timeout 1

# ssh command
spawn ssh -S ~/.ssh/tmp.$user_at_host -M -N -f $user_at_host

# deal with ssh prompts
expect {
    "*yes/no*" { send "yes\r" ; exp_continue }
    "*assword:" { send "$password\r" ; exp_continue }
}
Run Code Online (Sandbox Code Playgroud)

此脚本仅timeout 1在线路上终止,没有它只是挂起,并且只能通过用户交互(^C)终止.

当该spawn行是一个直接的ssh命令时,脚本立即终止,但这不是你的直接ssh.可能不同的是-f使它在后台运行的选项(但我尝试了没有它的脚本无济于事).

我读过这个interact或者expect eof可能会有所帮助,但我找不到真正能做到的正确的咒语.

我的问题(我认为)是如何制作一个期望脚本,产生一个后台进程,终止没有超时?


编辑:我应该期望(没有双关语意)"使用无密码ssh身份验证"的答案.虽然这是一个合理的建议,但在我的场景中它并不是合适的解决方案:在可信环境中自动测试vanilla已安装的系统,其中不希望/可能向图像添加可信密钥.

ssh scripting expect

8
推荐指数
2
解决办法
2万
查看次数

其他解决方案/语言优于基于TCL的Expect?

令人惊讶的是Expect(TCL)如何自动化我通常无法做的很多事情.

我以为我可以通过阅读一本书深入了解Expect,但在我这样做之前,我想问一下是否有其他解决方案/语言可以做到Expect的工作?

例如.我读过人们将Expect与Awk和Perl进行比较.

Awk和Perl可以做同样的事情吗?

那么像Python和Ruby这样的其他语言呢?

Expect是事实上的自动化工具还是其他解决方案/语言更优越?

python perl awk tcl expect

8
推荐指数
2
解决办法
1492
查看次数

如何在Process.StandardOutput中禁用输出缓冲

这个问题不止一次被问过,但我在任何讨论中都没有找到满意的答案.

我正在启动一个命令行过程,它可以对STDOUT进行实时测量,大约每秒产生一个新结果.使用System.Diagnostics.Process.StandardOutput导致完全不可接受的延迟(超过20秒),因为STDOUT数据通过Process.StandardOutput StreamReader中的4k缓冲区工作,并且似乎没有任何方法可以解决这个问题.

调用Process.StandardOutput.BaseStream.Flush()不起作用.

我试过对Process.StandardOutput进行逐字节同步读取,但是我仍然比实际输出落后4k.

任何人都可以至少验证我有可能以某种方式克服我重定向STDOUT时遇到的所有缓冲问题,并且一旦它出现在shell窗口中就会立即收到我的应用程序中的数据吗?我可以继承Process类并更改StandardOutput流读取器的行为吗?我是否需要查看原始的WINAPI呼叫?

不知何故,这必须要完成,即使我最终编写非托管C++来启动任务并使用输出,并将其连接起来.任何帮助都非常感谢; 我的智慧结束了......

编辑:看来我需要的是可用于C/C++,Perl,Python和Java的"期望"库的.Net实现(这是迄今为止我发现的唯一库).有谁知道这样的野兽是否存在?

c# winapi process expect buffering

8
推荐指数
1
解决办法
2438
查看次数

TCL期待正则表达


我正在尝试编写一个脚本,通过TCL/Expect从一个系统爬升到另一个系统.它对我有用.我需要一个正则表达式,其中期望"$"期望"#"被组合,以便可以包含路径中任何提示的任何系统.

#!/usr/bin/expect
# Using ssh from expect

log_user 0
spawn ssh test@192.168.2.24
expect "sword: "
send "test\r"
expect "$ "
send "ssh beta\r"
expect "# "
send "uptime\r"
expect "# "

set igot $expect_out(buffer)
puts $igot
Run Code Online (Sandbox Code Playgroud)

regex tcl expect

8
推荐指数
2
解决办法
7710
查看次数

$ expect_out如何在TCL/EXPECT中工作?

如果我想DEF_23使用以下正则表达式进行匹配:

expect {
    -re "DEF_\[0-9]*"
    set result $expect_out(1,string)
}
Run Code Online (Sandbox Code Playgroud)

为什么它说数组中没有这样的元素?这个$ expect_out如何运作?如果我想将结果分配为no such element in array,如何使用regexp获取DEF并分配给变量结果?

regex tcl expect

8
推荐指数
1
解决办法
3万
查看次数

从Python运行Expect脚本的最简单方法

我正在尝试指示我的Python安装执行Expect脚本"myexpect.sh":

#!/usr/bin/expect
spawn ssh usr@myip
expect "password:"
send "mypassword\n";
send "./mycommand1\r"
send "./mycommand2\r"
interact
Run Code Online (Sandbox Code Playgroud)

我在Windows上,所以将Expect脚本中的行重写为Python不是一种选择.有什么建议?有没有什么可以像"./myexpect.sh"从bash shell那样运行它?


我在subprocess命令上取得了一些成功:

subprocess.call("myexpect.sh",  shell=True)
Run Code Online (Sandbox Code Playgroud)

我收到错误:

myexpect.sh不是有效的Win32应用程序.

我该如何解决这个问题?

python ssh subprocess expect

8
推荐指数
1
解决办法
4万
查看次数

如何使用java实现expect"interact"命令

我想使用java实现expect"interact"命令.在期望中,可以打开ssh会话,进行身份验证,然后使用"interact"命令将控件返回给用户.这可能与Java?我已经尝试过expectJ,expect4J和expectForJava但是文档很少,几乎没有如何做到这一点的例子.TIA.

更新:对于"交互"命令参考,请查看:http://wiki.tcl.tk/3914

"Interact是一个Expect命令,它将当前进程的控制权交给用户,以便将键击发送到当前进程,并返回当前进程的stdout和stderr."

java unix tcl expect expectj

8
推荐指数
1
解决办法
2840
查看次数

如何在Expect脚本中使用$符号发送密码

我有一个期望脚本,我需要登录到远程系统并执行命令.此脚本适用于向root帐户提供密码的例外.root密码包含一个我似乎无法工作的美元符号.这是代码

#!/usr/bin/expect
set timeout 3
set username "root"
set password "Pas$word"
set hostname [lindex $argv 0]
log_user 0

send_user "\n#####\n# $hostname\n#####\n"

spawn ssh -q -o StrictHostKeyChecking=no $username@$hostname

expect {
    timeout { send_user "\nFailed to get password prompt\n"; exit 1 }
    eof { send_user "\nSSH failure for $hostname\n"; exit 1 }
    "*assword"
}

send "$password\r"

expect {
    timeout { send_user "\nLogin failed. Password incorrect.\n"; exit 1}
    "*\$ "
}

send_user "\nPassword is correct\n"

expect "$ " { send "ls" }
Run Code Online (Sandbox Code Playgroud)

我在提供密码不包含美元符号的凭据时验证了这一点,但我无法使用root帐户.它总是产生 …

authentication ssh bash expect remote-server

8
推荐指数
3
解决办法
2万
查看次数

如何使用shell命令的输出设置expect变量

我想在expect文件中设置一个变量b,这里最初我通过这个脚本ssh到一台机器,在那台机器上我想要获取一个值并使用以下命令设置expect变量:

set b [exec `cat /home/a |grep "work"|awk -F '=' '{print $2}'`]


send_user "$b"
Run Code Online (Sandbox Code Playgroud)

file/home/a有以下结构:

home=10.10.10.1

work=10.20.10.1
Run Code Online (Sandbox Code Playgroud)

我打算在打印后使用变量b但是在执行ssh脚本之后它会给出:

不能读"2":没有这样的变量

while executing
Run Code Online (Sandbox Code Playgroud)

如果我将此输出放在该机器的文件名temp中并尝试执行以下操作:

设置b [exec cat ./temp]

然后它还给出了:

cat:./ temp:没有这样的文件或目录

如果我发送"cat ./temp",它会输出正确的输出.

请让我知道我哪里出错了.

linux variables bash shell expect

8
推荐指数
2
解决办法
1万
查看次数