As per the below script, it adds both commands to output.txt.
Instead how to add "show system" command to output1.txt and "show run" command to output2.txt.
Python Script:
Import program dependencies
from netmiko import ConnectHandler
import getpass
Read from a list of hostnames to connect to
hosts = open('hosts.txt','r')
hosts = hosts.read()
hosts = hosts.strip().splitlines()
Get UserName and password from input
userName = input('Username: ')
passWord = getpass.getpass()
Loop to process hosts in hosts.txt file
for host in hosts:
# Define device type and connection attributes
Brocade_ICX = {
'device_type': 'brocade_fastiron',
'ip': host,
'username': userName,
'password': passWord),
}
# Netmiko SSH Connection Handler
net_connect = ConnectHandler(**Brocade_ICX)
#open file to write command output
file = open('output.txt', 'w')
# Execute commands
output = net_connect.send_command('show system')
output = net_connect.send_command('show run')
# Print output to console screen
print('-------------- Output from ' + host + '------------------')
print(output)
print()
print()
# Write output to file above
file.write(output)
file.close()
you are doing the looping wrong..
think about the last iteration of j variable in the loop
it points to c then inner loop goes through each file and and writes c to them
to fix it you need only one loop
for i in range(len(command)):
file = open(command[i] +'_output.txt', 'w')
file.write(output[i])
file.close()
Follow just four simple steps to get the solution.
Opening a text file.
file = open('text file','w')
Adding a test line in the file.
file.write('We will be seeing aninterated printing of numbers between 0 to 10\n')
Writing a for loop over the file.
for i in range(0,11):
file.write(str(i))
file.write('\n')
Closing the text file.
file.close()
Related
This program is to login to my switch and copies output to a file; and the second part is for finding a keyword and print the entire line.
When I run the code the first part works fine but second part of the code does not print the line containing the key word i am looking for..
However, when i run the second part of the code separately i am able to print the line containing the key_word.
What is wrong here? Pease help me out?
import paramiko
import sys
import re
host = "15.112.34.36"
port = 22
username = "admin"
password = "ssmssm99"
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(host, port, username, password)
commands = ["switchshow"]
for command in commands:
print(command)
sys.stdout = open('zones_list.txt', 'w')
stdin, stdout, stderr = ssh.exec_command(command)
lines = stdout.readlines()
lines = "".join(lines)
print(lines)
ssh.close()
#SECOND PART
#open the zone_list file and search for a keyword
#search for wwn and print the entire line --> doesnt print why?
wwn = "10:00:00:90:fa:73:df:c9"
with open('zones_list.txt', 'r') as f:
lines = f.readlines()
for line in lines:
if re.search(r'10:00:00:90:fa:73:df:c9', line):
print (line)
break
You're redicting stdout to a file in line 17:
sys.stdout = open('zones_list.txt', 'w')
All print statements afterwards don't write to the console, but to the file.
Secondly you open the same file twice, once for writing and once for reading, but in the second case f.readlines() returns an empty list.
Example to show why it's problematic to open the file twice.
import sys
# 1. Opening the file without closing it => will be closed at the end of the program
# 2. stdout now writes into the file
sys.stdout = open('text3', 'w')
# Will be writen into the file when the program finishes
print ('line1')
print ('line2')
# We open the file a second time
with open('text3', 'r') as f:
# lines will always be an empty list, no matter if there was something in the file before
lines = f.readlines()
# Writing to stderr so we see the output in the console (stdout still points at the file)
sys.stderr.write('length: {}'.format(len(lines)))
for line in lines:
# We should never be here
sys.stderr.write (line)
# write some more stuff the the file
for i in range(1, 6):
print ('i + {}'.format(i))
print('line3')
The first part of the script redirected stdout to the file. So print(line) in the second part is also writing to the file instead of displaying the matching line. Also, you never closed the file in the first part, so buffered output won't be written to the file.
Don't use sys.stdout in the first part, use an ordinary variable.
Another problem is that you're overwriting the file for each command in commands. You should open the file once before the loop, not each time through the loop.
wwn isn't a regular expression, there's no need to use re.search(). Just use if wwn in line:. And you don't need to use f.readlines(), just loop through the file itself.
import paramiko
import sys
host = "15.112.34.36"
port = 22
username = "admin"
password = "ssmssm99"
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(host, port, username, password)
commands = ["switchshow"]
with open('zones_list.txt', 'w') as f:
for command in commands:
print(command)
stdin, stdout, stderr = ssh.exec_command(command)
lines = stdout.readlines()
lines = "".join(lines)
print(lines, file=f)
ssh.close()
#SECOND PART
#open the zone_list file and search for a keyword
#search for wwn and print the entire line --> doesnt print why?
wwn = "10:00:00:90:fa:73:df:c9"
with open('zones_list.txt', 'r') as f:
for line in f:
if wwn in line:
print (line)
break
got the code straight. And couple of questions to bug you and Maddi.
This code asks the user to enter the "wwn" to search for in the host and print the line which contains the "wwn" number.
Question1: I would run this code multiple times whenever I would like to search for "wwn"...
And here I would like to have a clear "zones_list.txt" file each time I start. So I opened the file in 'w' mode -- SO this clears each time right? Any other suggestion?
Question2: IS there any other way to store the output and search it for a string and print the output? I guess storing the data in a file and searching through it is the best?
Question3: I would like to add a GUI where user is asked to enter the "wwn" and print the output. Any suggestion?
Thanks again :)
import paramiko
import sys
import re
#host details to fetch data - nodefind
host = "15.112.34.36"
port = 22
username = "admin"
password = "ssmssm99"
#shell into the client host
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(host, port, username, password)
#asking user to enter the wwn to search in the host
wwn = input('Enter the wwn to be searched >')
#for example command is: nodefind 20:34:00:02:ac:07:e9:d5
commands = ["nodefind " + wwn, "switchshow"]
f =open('zones_list.txt', 'w')
for command in commands:
print(command)
stdin, stdout, stderr = ssh.exec_command(command)
lines = stdout.readlines()
lines = "".join(lines)
print(lines, file=open('zones_list.txt', 'a'))
ssh.close()
#print a particular line in console to the user
f =open('zones_list.txt', 'r')
for line in f:
if wwn in line:
print(line)
break
I am trying to tail a log file on a remote server using a Python script. The log file rolls over very fast, I am using the python-sshtail module to tail the log file and capture the output of the tail in a file on my local machine. I was able to capture the log file and save it to a file on my local machine but the my script seems to be writing it twice and data is formatted.
The script is working but not the way I want it to, I should be able to run the script, perform some actions on the servers, tail the logs, save the output to a file on my local machine and kill the script using CTRL-C.
I did write some code and it does work but not the way it should. For now I am using time.sleep to wait for the output to be written to the output file on my local machine.
#!/usr/bin/python3
import time
import sshtail.tailers as t
import sys
import datetime
username = "username"
logfile = "/var/log/file.log"
k = t.paramiko.RSAKey.from_private_key_file('keyfile')
conn = t.SSHTailer(username,logfile, k, verbose=True)
try:
conn.connect()
print(f"Connected to {conn.host}")
print("Tailing the file..")
except:
print("Connection unsuccesful...")
conn.tail()
for line in conn.tail():
print(line)
for line in conn.get_new_lines():
print(line)
x = conn.remote_file_size
print(f"The file size is: {x}")
time.sleep(10)
output_file = str(conn.host)+"_"+str(datetime.datetime.now().strftime("%Y-%m-%d_%H:%M:%S"))+".txt"
with open(output_file, "a") as f:
for line in conn.get_new_lines():
print(line)
f.write(line)
conn.disconnect()
I recommend replacing time.sleep with asyncio.sleep
I want to send 'hello world' to a script in python already running in ubuntu.
The script that's always running is this one (part of it):
print("$ echo 'foobar' > {0}".format(get_ttyname()))
print("$ echo 'foobar' > /proc/{0}/fd/0".format(os.getpid()))
sys.stdin.readline()
it throws the pid of the running process so I can send stuff by console with:
echo 'hello script!' > /proc/PID/fd/0
It will print it in the console! but I can't send \x15 or EOF or anything to break sys.stdin.readline() and do some other stuff in my script, for example:
def f(e):
print 'we already read:',s
while True:
s = sys.stdin.readline()
print 'we break the readline'
f(s)
.....blablabla some other stuff, and then we return to the top of the while to keep reading...
Does anyone know how to do it? The script that send the string will not always be running, but the script that receives the info will be always running.
PROBLEM SOLVED!
Thank's to Rafael this is the solution:
Reader:
import os
import sys
path = "/tmp/my_program.fifo"
try:
os.mkfifo(path)
except OSError:
pass
fifo = open(path, "r")
while True:
for line in fifo:
linea = line
print "Received: " + linea,
fifo.close()
if linea =='quit':
break
fifo = open(path, "r")
Sender:
# -*- coding: utf-8 -*-
import os
path = "/tmp/my_program.fifo"
fifo = open(path, "w")
fifo.write("Hello Wordl!!\n")
fifo.close()
Since you obviously don't have a problem with being limited to a Unix system, you can use named pipes to communicate with the program. Very unix-y way to work.
Python provides the os.mkfifo function to ease creating named pipes; otherwise they work just like files.
Write to a text file that is read by the already running program. The two can interact via this file. For example, these two programs simultaneously read and write to an initially empty text file.
already.py
# executed 1st
import time
while True:
text = open('file.txt').read()
print 'File contents: ' + text
time.sleep(5)
program.py
# executed 2nd
import time
while True:
text = open('file.txt', 'a')
text.write(raw_input('Enter data: '))
text.close()
time.sleep(5)
I was wondering if the community can help me out I'm a newbie to programming. I trying to ssh to a list of devices contain on "list.txt" once it logs into the router I send the same command to each one and write the output to a file. However, on the code below it overrides the output of each device. I need to create a unique file for each output with the name of the IP address that is contains on the "list.txt" file. If anybody can help me out I would really appreciated.
import paramiko
import time
import os
def disable_paging(remote_conn):
'''Disable paging on a Cisco router'''
remote_conn.send("terminal length 0\n")
time.sleep(1)
# Clear the buffer on the screen
output = remote_conn.recv(1000)
return output
#Create variables
f = open('list.txt')
filepath = ('test/tas.txt')
username = 'test'
password = 'test'
#Create a for loop
for i in f:
remote_conn_pre = paramiko.SSHClient()
remote_conn_pre.set_missing_host_key_policy(
paramiko.AutoAddPolicy())
remote_conn_pre.connect(i, username=username, password=password)
remote_conn = remote_conn_pre.invoke_shell()
output = remote_conn.recv(1000)
disable_paging(remote_conn)
# Now let's try to send the router a command
remote_conn.send("\n")
remote_conn.send("show int des\n")
# Wait for the command to complete
time.sleep(2)
output = remote_conn.recv(88880000)
# print output
if not os.path.exists(os.path.dirname(filepath)):
os.makedirs(os.path.dirname(filepath))
with open(filepath, "w") as f:
f.write(output)
f.close()
You could just have your 'filepath' variable defined in the for loop, and use the 'i' string to create it :
for i in f:
filename = 'tas_%s.txt' % str(i)
filepath = os.path.join('test', filename)
# anything else remains unchanged
Hope it works (difficult without knowing the content of 'list.txt').
I am new to Python and have just successfully completed writing and testing a script that will do the following:
Telnet into the switch.
Log in with credentials provided.
Open a file and then redirect the output of the commands to it.
Logout from the switch once done.
What I wish it to do:
I want my script to create a file in the specified directory using the IP address of the switch. Like configuration from switch with the IP address of 192.168.1.30 should be saved as 192.168.1.30.txt.
Below is a part of my script
============================
#!/usr/bin/python
import pexpect
import datetime
HOST = raw_input ("Enter the IP Address Of the switch:")
user=admin
password=admin
child = pexpect.spawn ('telnet', [HOST])
child.logfile = open("/home/tester/scripts/config.txt", "w")
==============================
As you can see if I ran the above script, the output of the commands sent via the script will be saved to the config.txt file. The contents will be erased if a different switch is telnet'd into and contents from the new switch will be saved. So, I would like the script to use the IP address entered by the user and then save the output of the commands in a different file using the IP address as the filename, so that contents of the file do not get over-written.
Any advice will be appreciated!
Thank you
Since HOST is the string "192.168.1.30", and you want the file to be named "/home/tester/scripts/192.168.1.30.txt", you can do this with simple string concatenation:
path = "/home/tester/scripts/" + HOST + ".txt"
… or, better, with string formatting:
path = "/home/tester/scripts/{}.txt".format(HOST)
Then:
child.logfile = open(path, "w")
(Of course you can also do the concatenation or format right in the middle of the open expression, if you prefer, but I think it's more readable this way.)