如何制作期望时间戳日志文件

How to make expect timestamp logfile

我正在尝试让我的 expect 脚本创建一个带有时间戳的日志文件,并在下次 运行s 时创建另一个带有时间戳的日志文件,但找不到有关如何操作的任何信息。

我有一个文件,其中包含期望连接的主机列表和 运行 一组命令,当它 运行 时,我想在一个文件中记录所有事件。

Host1
Host2
Host3
etc

我已经设法创建带有时间戳的日志文件:

log_file -a ~/log/[exec date]_results.log

也试过:

log_file -a -noappend ~/log/[exec date]_results.log

但它会为每一行主机创建一个新主机:

Thu Mar  8 15:28:24 CET 2018_results.log
Thu Mar  8 15:28:25 CET 2018_results.log
Thu Mar  8 15:28:26 CET 2018_results.log
Thu Mar  8 15:28:27 CET 2018_results.log
Thu Mar  8 15:28:28 CET 2018_results.log

我找到了一个解决方案。

将此添加到我的 .sh

timestamp=`date +%y-%m-%d_%H:%M`
logdir=~/log/

# This will rotate and append date stamp...
logfile=$logdir/results.log
newlogfile=$logfile.$timestamp
cp $logfile $newlogfile

这有效,但只会向旋转文件添加时间戳,results.log 文件将是最新的,并且旋转文件将带有日期和时间戳记,从您 运行脚本,因此该文件的时间戳将是错误的。

这里有 .sh 和 .exp 脚本,如果有解决方案可以为所有文件加上正确的时间戳 date/time。

.sh:

#!/bin/bash
 # Collect the current user's ssh password file to copy.
 echo -n "Enter the telnet password for $(whoami) : "
 read -s -e password
 echo -ne '\n'
 echo -n "Enter the command to run on device : "
 read -e command
 echo -ne '\n'

timestamp=`date +%y-%m-%d_%H:%M`
logdir=~/log/

# This will rotate and append date stamp...
logfile=$logdir/results.log
newlogfile=$logfile.$timestamp
cp $logfile $newlogfile

names=()
ips=()
n=0
while read name ip; do
  [[ -z $ip ]] && continue
  names[n]=$name
  ips[n]=$ip
  ((++n))
done < hostlist

for ((i=0; i<n; ++i)); do
  ./script.exp ${names[i]} ${ips[i]} $device "$password" "$command"
done

.exp:

#!/usr/bin/expect -f

# Set variables
 set hostname [lindex $argv 0]
 set ipadd    [lindex $argv 1]
 set username $env(USER)
 set password [lindex $argv 2]
 set command  [lindex $argv 3]
 set timeout 20
# Log results
 log_file -a ~/log/results.log            
# Announce which device we are working on and at what time
 send_user "\n"
 send_user ">>>>>  Working on $hostname @ [exec date] <<<<<\n"
 send_user "\n"

 expect_after timeout {send_user "Timeout happened connecting to $hostname; So, exiting....";exit 0}

 spawn telnet $hostname
 expect "*sername:"
 send   "$username\n"
 expect "*assword:"
 send "$password\n"
 expect "*#"
 send "$command $ipadd\n"
 expect "*#"
 send "exit\n"
 expect ":~$"
 exit

您可以在 Expect 中执行所有这些操作:

#!/usr/bin/expect -f

set host_file "hostlist"
if {![file readable $host_file]} {
    error "cannot read $host_file"
}

# get info from user
set me [exec whoami]
stty -echo
send_user "Enter the telnet password for $me : "
expect_user -re {(.*)\n}
set password $expect_out(1,string)
send_user "\n"
stty echo

send_user "Enter the command to run on device : "
expect_user -re {(.*)\n}
set command $expect_out(1,string)

set timestamp [timestamp -format %Y-%m-%d_%H:%M]
set logfile $env(HOME)/log/results_$timestamp.log
log_file -a $logfile

expect_after timeout {send_user "Timeout happened connecting to $hostname; So, exiting....";exit 0}

set fh [open $host_file r]
while {[gets $fh line] != -1} {
    lassign [regexp -all -inline {\S+} $line] hostname ip
    if {$hostname eq "" || $ip eq ""} continue

    send_user "\n"
    send_user ">>>>>  Working on $hostname @ [timestamp -format %c] <<<<<\n"
    send_user "\n"

    spawn telnet $hostname
    expect "*sername:"
    send   "$me\r"
    expect "*assword:"
    send   "$password\r"
    expect "*#"
    send   "$command $ip\r"
    expect "*#"
    send   "exit\r"
    expect eof
}

要处理用户输入超时,有两种策略:

  1. timeout变量设置为-1无限期等待:

    set prev_timeout $timeout
    set timeout -1
    send_user "Enter the thing: "
    expect_user -re "(.*)\n"            ;# waits forever
    set the_thing $expect_out(1,string)
    set timeout $prev_timeout
    
  2. 使用无限循环向用户提供反馈

    while 1 {
        send_user "Enter the thing: "
        expect_user {
            -re "(.*)\n" {break}
            timeout {send_error "timeout!\n"}
        }
    }
    set the_thing $expect_out(1,string)