编辑:我通过引用《Exploring Expect》一书找到了答案。不过,请随时添加我的答案或提出其他建议!当我被允许时(从现在起 2 天后),我会将其标记为已回答。
我环顾四周,不幸的是我在这个网站上找不到太多关于使用 SSH 和 Expect 的信息。我对 Expect 还比较陌生,但我一直在通过《Exploring Expect》一书自学。
我的问题是:如何将单个生成的 SSH 进程用于多个 tcl 过程?我现在的解决方法是在过程 1 结束时关闭 SSH 连接,并在过程 2 中重新生成新的 SSH 连接。
示例:(该示例被简化了很多,只包含了演示我的问题所必需的组件...到目前为止,我的整个程序已超过 200 行)
;# Proc definition for procedure1
proc procedure1 {user host pw} {
spawn /usr/bin/ssh $user@$host
expect "Password:"
send "$pw\r"
expect "#" ;# This is my device's prompt
;# From here it does a bunch of stuff... sends commands to the SSH
;# session, captures output, builds arrays and lists, etc
send "exit" ;# Disconnects the SSH session
return $mylist ;# returns a list of numbers to be used in procedure 2
}
;# Proc definition for procedure2
proc procedure2 {resultofproc1 user host pw} {
spawn /usr/bin/ssh $user@$host
expect "Password:"
send "$pw\r"
expect "#" ;# This is my device's prompt
;# Proc 2 now continues on in the same device using the results (a
;# list) from proc1.
return
}
;# Procedure call for first procedure:
set resultofproc1 "[procedure1 $user $host $pw]"
;# Procedure call for second procedure:
procedure2 $resultofproc1 $user $host $pw
如何将命令从 procedure2 发送到 procedure1 中打开的 SSH 连接,而不是在 procedure1 结束时关闭 SSH 连接并在 procedure2 开始时重新打开 SSH 连接?显然,我必须删除发送退出以保持连接打开。假设这是可能的......这是否是一个好的实践,或者我最好分离过程之间的连接?如果是这样,您可以修改我的代码示例来演示如何操作吗?
根据我收集的信息,我认为这与 spawn_id 变量有关。但我不知道如何在我的代码中实现它。我目前正在复习《Exploring Expect》一书中的第 10 章“处理多个进程”。如果我能自己解决的话,我会报告。
感谢您的帮助!
我在 stackoverflow 上查看了这些答案:
Tcl Expect Keep SSH Spawn open
Expect Procedure for SSH Login
Using procedure for spawing SSH doesn't work properly with expect
最佳答案
您可以使用global申报spawn_id
作为一个全局变量。根据expect的手册:
CAVEATS
block 引用>...
Expect takes a rather liberal view of scoping. In particular, variables read by commands specific to the Expect program will be sought first from the local scope, and if not found, in the global scope. For example, this obviates the need to placeglobal timeout
in every procedure you write that usesexpect
. On the other hand, variables written are always in the local scope (unless aglobal
command has been issued). The most common problem this causes is whenspawn
is executed in a procedure. Outside the procedure,spawn_id
no longer exists, so the spawned process is no longer accessible simply because of scoping. Add aglobal spawn_id
to such a procedure.
...
您还可以利用 Tcl 的 upvar命令。例如:
[STEP 101] $ cat foo.exp proc expect_prompt {} { upvar spawn_id spawn_id expect -re {bash-[.0-9]+[#$] $} } proc open_conn {} { upvar spawn_id spawn_id spawn bash --noprofile --norc expect_prompt } proc close_conn {} { upvar spawn_id spawn_id send "exit\r" expect eof } proc send_cmd { cmd } { upvar spawn_id spawn_id send "$cmd\r" expect_prompt } proc main {} { open_conn send_cmd "echo spawn_id=$spawn_id" send_cmd "ps Tu" close_conn } main [STEP 102] $
输出:
[STEP 103] $ expect foo.exp spawn bash --noprofile --norc bash-4.4$ echo spawn_id=exp6 spawn_id=exp6 bash-4.4$ ps Tu USER PID %CPU %MEM VSZ RSS TT STAT STARTED TIME COMMAND root 71513 0.0 0.0 2433012 788 s013 R+ 12:58PM 0:00.00 ps Tu pynexj 71510 0.0 0.0 2445360 1572 s013 Ss 12:58PM 0:00.01 bash --noprofile --norc bash-4.4$ exit exit [STEP 104] $
关于ssh - 如何在 TCL Expect 中的多个程序之间共享生成的 SSH 进程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44600154/