如何使期望时间戳日志文件

时间:2018-03-08 14:52:49

标签: bash expect

我试图让我的期望脚本创建一个带有时间戳的日志文件,并在下次运行时使用时间戳创建另一个,但无法找到有关如何的任何信息。

我有一个文件,其中包含一系列主机,这些主机希望连接并运行一组命令,我希望在运行时将所有事件记录在一个文件中。

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脚本。

.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

1 个答案:

答案 0 :(得分:1)

您可以在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)