【发布时间】:2014-02-02 07:17:59
【问题描述】:
我正在尝试使用 spawn 远程登录到多个服务器,并且我想将每个服务器的输出记录在单独的文件中。 如果我使用带有'logfile'的spawn,那么它正在登录到同一个文件。但我想把它放在不同的文件中。这该怎么做?
【问题讨论】:
-
您能否提供一些基本代码来展示您如何创建子流程和设置日志记录。
我正在尝试使用 spawn 远程登录到多个服务器,并且我想将每个服务器的输出记录在单独的文件中。 如果我使用带有'logfile'的spawn,那么它正在登录到同一个文件。但我想把它放在不同的文件中。这该怎么做?
【问题讨论】:
Expect 的日志记录支持(即log_file 命令控制的内容)不允许您为不同的生成 ID 设置不同的日志记录目标。这意味着做你想做的最简单的机制是在一个单独的进程中运行每个期望会话,如果你不使用interact 命令,这应该不会太难。 (需要同时与多个远程会话进行交互的想法有点奇怪!当您通过嫁接屏幕程序之类的东西使其变得明智时,您可能还不如使用单独的期望脚本。)
在最简单的情况下,您的外部脚本可以是:
foreach host {foo.example.com bar.example.com grill.example.com} {
exec expect myExpectScript.tcl $host >@stdout 2>@stderr &
}
(>@stdout 2>@stderr & 确实“在后台运行,标准输出和标准错误连接到通常的总体目标。)
如果您想在期望会话之间自动传递有关信息,事情会变得相当复杂。我希望简单就足够了……
【讨论】:
我从链接中找到了一些东西
LogScript.tcl
#!/usr/bin/tclsh8.5
package require Expect
proc log_by_trace {array element op} {
uplevel {
global logfile
set file $logfile($expect_out(spawn_id))
puts -nonewline $file $expect_out(buffer)
}
}
array set spawns {}
array set logfile {}
# Spawn 1
spawn ./p1.sh
set spawns(one) $spawn_id
set logfile($spawn_id) [open "./log1" w]
# Spawn 2
spawn ./p2.sh
set spawns(two) $spawn_id
set logfile($spawn_id) [open "./log2" w]
trace add variable expect_out(buffer) write log_by_trace
proc flush_logs {} {
global expect_out
global spawns
set timeout 1
foreach {alias spawn_id} [array get spawns] {
expect {
-re ".+" {exp_continue -continue_timer}
default { }
}
}
}
exit -onexit flush_logs
set timeout 5
expect {
-i $spawns(one) "P1:2" {puts "Spawn1 got 2"; exp_continue}
-i $spawns(two) "P2:2" {puts "spawn2 got 2"; exp_continue}
}
p1.sh
#!/bin/bash
i=0
while sleep 1; do
echo P1:$i
let i++
done
p2.sh
#!/bin/bash
i=0
while sleep 1; do
echo P2:$i
let i++
done
它工作得很好:)
【讨论】: