/sys/admin

Blog de/para sysadmins, devops y fans de GNU/Linux

Feb 19 15 17:17
Sendlines, Un Expect Simplificado

Comments

Para automatizar tareas siempre había hecho uso de autoexpect, ya que, una vez realizado (y guardado) todo la primera vez, sólo había que hacer un par de apaños al script resultante. Sin embargo, hay veces que no necesitamos algo tan sofisticado o no queremos instalar tcl/tsh en la máquina.

No hay problema: un pequeño script en python lee de un archivo de texto y le manda, línea a línea, su contenido al ejecutable que hayamos elegido.

Seguramente haya muchas cosas por pulir, pero hace lo que tiene que hacer (Pricipio KISS, que le llaman ;) ).

Uso: sendlines -f Fichero_de_texto -c "comando a ejecutar" [ -d delay ], donde:

  • fichero_de_texto: archivo que contiene las lineas que se van a mandar. No contempla comentarios, lo manda del tirón
  • comando: orden que recibirá las entradas de fichero_de_texto. Si tiene parámetros, poner todo el comando entre comillas (ej: "grep -v grep")
  • delay: tiempo entre lineas. Opcional, espera un tiempo (en segundos) entre cada linea que manda

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import subprocess
import time
import sys, getopt

def run(cmd,textFile,delay):
	with open(textFile,'r') as text:
		content=text.readlines()
	p = subprocess.Popen(cmd,stdout=subprocess.PIPE,stdin=subprocess.PIPE)
	for line in content:
		p.stdin.write(line+'\n')
		if(delay): time.sleep(float(delay))
	p.communicate()[0]
	p.stdin.close()

def usage():
	print '''
		Usage: sendlines -f textFile -c "COMMAND" [ -d DELAY ]
		- textFile: Text file where read lines from. Mandatory.
		- COMMAND: Command to be executed (if there are any arguments to be sent, must be put all between quotes). Mandatory
		- DELAY: Time (in seconds) to wait between sending lines. Optional.
		'''
if __name__ == "__main__":
	textFile = None
	command = None
	delay = None
	try:
		opts, args = getopt.getopt(sys.argv[1:], "f:c:d:", ["file=", "command=", "delay="])
	except getopt.GetoptError as err:
		# print help information and exit:
		print str(err) # will print something like "option -a not recognized"
		sys.exit(2)
	for o, a in opts:
		if o in ("-f", "--file"):
			textFile = a
		elif o in ("-c", "--command"):
			command = a.split(' ')
		elif o in ("-d", "--delay"):
			delay = a
		else:
			assert False, "unhandled option"
			usage()
	if(command and textFile):
		run(command,textFile,delay)
	else:
		usage()
		print 'Missing argument(s). Exit\n'
		sys.exit(2)