所以我想自动化我的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中自动输入密码的经典问题,就像其他人一样,我在黑暗中磕磕绊绊地期待着.最后,我拼凑了一个有点工作的脚本:
#!/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已安装的系统,其中不希望/可能向图像添加可信密钥.
令人惊讶的是Expect(TCL)如何自动化我通常无法做的很多事情.
我以为我可以通过阅读一本书深入了解Expect,但在我这样做之前,我想问一下是否有其他解决方案/语言可以做到Expect的工作?
例如.我读过人们将Expect与Awk和Perl进行比较.
Awk和Perl可以做同样的事情吗?
那么像Python和Ruby这样的其他语言呢?
Expect是事实上的自动化工具还是其他解决方案/语言更优越?
这个问题不止一次被问过,但我在任何讨论中都没有找到满意的答案.
我正在启动一个命令行过程,它可以对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实现(这是迄今为止我发现的唯一库).有谁知道这样的野兽是否存在?
我正在尝试编写一个脚本,通过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) 如果我想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并分配给变量结果?
我正在尝试指示我的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应用程序.
我该如何解决这个问题?
我想使用java实现expect"interact"命令.在期望中,可以打开ssh会话,进行身份验证,然后使用"interact"命令将控件返回给用户.这可能与Java?我已经尝试过expectJ,expect4J和expectForJava但是文档很少,几乎没有如何做到这一点的例子.TIA.
更新:对于"交互"命令参考,请查看:http://wiki.tcl.tk/3914
"Interact是一个Expect命令,它将当前进程的控制权交给用户,以便将键击发送到当前进程,并返回当前进程的stdout和stderr."
我有一个期望脚本,我需要登录到远程系统并执行命令.此脚本适用于向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帐户.它总是产生 …
我想在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",它会输出正确的输出.
请让我知道我哪里出错了.