Declaración condicional dentro del comando esperar llamado desde un script bash
Pregunta
He estado tratando de automatizar algunas copias de seguridad de configuración en mis dispositivos Cisco, ya he logrado hacer el script que realiza la tarea, pero también estoy tratando de mejorarlo para manejar errores.
Creo que es necesario detectar los errores en dos pasos, primero justo después de 'enviar \' '$ pass \ r \' ' para obtener errores de inicio de sesión (acceso a mensajes denegados) y en el 'esperar \' ': final \' '' línea, para asegurarse de que los comandos emitidos pudieron extraer la configuración del dispositivo.
He visto algunas formas de hacerlo si trabaja en un script esperado, pero quiero usar un script bash para poder proporcionar una lista de dispositivos desde un archivo .txt.
#!/bin/bash
data=$(date +%d-%m-%Y)
dataOntem=$(date +%d-%m-%Y -d "-1 day")
hora=$(date +%d-%m-%Y-%H:%M:%S)
log=/firewall/log/bkpCisco.$data.log
user=MYUSER
pass=MYPASS
for firewall in `cat /firewall/script/firewall.cisco`
do
VAR=$(expect -c "
spawn ssh $user@$firewall
expect \"assword:\"
send \"$pass\r\"
expect \">\"
send \"ena\r\"
expect \"assword:\"
send \"$pass\r\"
expect \"#\"
send \"conf t\r\"
expect \"conf\"
send \"no pager\r\"
send \"sh run\r\"
log_file -noappend /firewall/backup/$firewall.$data.cfg.tmp
expect \": end\"
log_file
send \"pager 24\r\"
send \"exit\r\"
send \"exit\r\"
")
echo "$VAR"
done
Solución
Necesita patrones alternativos en las declaraciones de espera donde desea detectar errores. Si está buscando un mensaje de error específico, puede especificarlo, o simplemente especificar un controlador de tiempo de espera que eventualmente se activará cuando la salida normal no aparezca.
Ej. después de enviar \ " $ pass \ r \ "
en lugar de esperar \ " > \ "
intente:
expect \">\" {} timeout {puts stderr {Could not log in}; exit}
es decir. si la salida esperada llega antes del tiempo de espera (predeterminado 10 segundos) no haga nada y continúe, de lo contrario, se quejará y saldrá de la espera. También es posible que necesite un patrón eof para que coincida con el caso en que finaliza su sesión ssh.
Tenga en cuenta que, dado que no realiza ninguna sustitución de variables en esperar, no necesita \ " \ " alrededor de sus cadenas, puede usar {} o incluso nada cuando es una palabra, por ejemplo. wait conf
y send {no pager}
.
Por cierto, estoy de acuerdo con bstpierre en que esto sería más limpio si dejases bash e hiciste todo lo esperado, pero si bash hace el trabajo, está bien.
Otros consejos
Si no utiliza comillas simples ( expect -c '...'
), todas las variables $ serán sustituidas por bash not expect. Puede ser más fácil colocar el código esperado en un archivo separado, o tal vez en un documento heredoc.