Прежде всего, я бы использовал для этого сценарий ожидаемого сценария и потерял бы сценарий bash.
Тогда для ожидаемой части:
Вы можете сделать это, используя переключатель, который также соответствует тайм-ауту (страница 12 исследования ожидаемого). Таким образом, вы можете явно действовать, когда ожидаете тайм-ауты.
В противном случае, установив таймаут, он просто продолжит выполнение следующей команды в строке.
set timeout 60
expect {
"assword:" {
}
timeout {
exit 1 # to exit the expect part of the script
}
}
Я создал нечто похожее, где я использовал общий сценарий ожидания для параллельного запуска сценария ожидания.
multiple.exp
#!/bin/sh
# the next line restarts using tclsh \
exec expect "$0" "$@"
# multiple.exp --
#
# This file implements the running of multiple expect scripts in parallel.
# It has some settings that can be found in multiple.config
#
# Copyright (c) 2008
#
# Author: Sander van Knippenberg
#####
# Setting the variables
##
source [file dirname $argv0]/.multiple.config
# To determine how long the script runs
set timingInfo("MultipleProcesses") [clock seconds]
# ---------------------------------------------------------------------
######
# Procedure to open a file with a certain filename and retrieve the contents as a string
#
# Input: filename
# Output/Returns: content of the file
##
proc openFile {fileName} {
if {[file exists $fileName] } {
set input [open $fileName r]
} else {
puts stderr "fileToList cannot open $fileName"
exit 1
}
set contents [read $input]
close $input
return $contents
}
######
# Procedure to write text to a file with the given filename
#
# Input: string, filename
##
proc toFile {text filename} {
# Open the filename for writing
set fileId [open $filename "w"]
# Send the text to the file.
# Failure to add '-nonewline' will reslt in an extra newline at the end of the file.
puts -nonewline $fileId $text
# Close the file, ensuring the data is written out before continueing with processing
close $fileId
}
# ---------------------------------------------------------------------
# Check for the right argument
if {$argc > 0 } {
set hostfile [lindex $argv 0]
} else {
puts stderr "$argv0 --- usage: $argv0 <hosts file>"
exit 1
}
# Create the commands that can be spawned in parallel
set commands {}
# Open the file with devices
set hosts [split [openFile $hostfile] "\n"]
foreach host $hosts {
if { [string length $host] > 1 } {
lappend commands "$commandDir/$commandName $host" # Here you can enter your own command!
}
}
# Run the processes in parallel
set idlist {}
set runningcount 0
set pattern "This will never match I guess"
# Startup the first round of processes until maxSpawn is reached,
# or the commands list is empty.
while { [llength $idlist] < $maxSpawn && [llength $commands] > 0} {
set command [lindex $commands 0]
eval spawn $command
lappend idlist $spawn_id
set commands [lreplace $commands 0 0]
incr runningcount
set commandInfo($spawn_id) $command
set timingInfo($spawn_id) [clock seconds]
send_user " $commandInfo($spawn_id) - started\n"
}
# Finally start running the processes
while {$runningcount > 0} {
expect {
-i $idlist $pattern {
}
eof {
set endedID $expect_out(spawn_id)
set donepos [lsearch $idlist $endedID]
set idlist [lreplace $idlist $donepos $donepos]
incr runningcount -1
set elapsedTime [clock format [expr [clock seconds] - $timingInfo($endedID)] -format "%M:%S (MM:SS)"]
send_user " $commandInfo($endedID) - finished in: $elapsedTime\n"
# If there are more commands to execute then do it!
if {[llength $commands] > 0} {
set command [lindex $commands 0]
eval spawn $command
lappend idlist $spawn_id
set commands [lreplace $commands 0 0]
incr runningcount
set commandInfo($spawn_id) $command
set timingInfo($spawn_id) [clock seconds]
}
}
timeout {
break
}
}
}
set elapsed_time [clock format [expr [clock seconds] - $timingInfo("MultipleProcesses")] -format "%M:%S (MM:SS)"]
send_user "$argv0 $argc - finished in: $elapsedTime\n"
multiple.config
# The dir from where the commands are executed.
set commandDir "/home/username/scripts/expect/";
set commandName "somecommand.exp";
# The maximum number of simultanious spawned processes.
set maxSpawn 40;
# The maximum timeout in seconds before any of the processes should be finished in minutes
set timeout 20800;