I am trying to connect to the server via ssh and dump the "df- h" output in some text file.
p=pexpect.spawn('ssh some.some.com')
i=p.expect([ssh_newkey,'password:',pexpect.EOF])
if i==0:
print "I say yes"
p.sendline('yes')
i=p.expect([ssh_newkey,'password:',pexpect.EOF])
if i==1:
p.sendline("somesome")
p.expect(pexpect.EOF)
i = p.sendline('df -h > /home/test/output.txt')
print i
response = p.before
print response
print p.before
I am trying to connect to the server and dump the server data in some text file.
My problem is i = p.sendline('df -h > /home/test/output.txt') is not doing anything,
Basically my output file is empty.
Please help me out.
Thanks.
You probably want to use paramiko to manage operations over an SSH connection.
My problem is i = p.sendline('df -h >
/home/test/output.txt') is not doing
anything
Isn't it setting i to 29? Is that what you mean?
Basically my output file is empty.
How do you know that? Nothing in this code is checking whether that file exists on the remote machine.
Please help me out.
Does your user on the remote machine have permission to write to the /home/test directory there, indeed, does that directory even exist? You're really giving us too few hints at exactly what you're doing, in exactly what context, and what exactly happens as a result, to be of any help yet, except for peppering you with such questions hoping you'll eventually tell us the many crucial pieces of data you're simply omitting. Help us help you out!-)
If you find yourself doing a lot of work over ssh to the same machines then you may want to look into something like func.
It looks like you're using Python as a shell here. Why don't you just save the relevant commands in a bash file and run that in one command instead? I think that'd work out a lot better. I also recommend that you enable SSH publickey authentication, it works better than passwords. Use the subprocess module to spawn processes from inside Python.
I guess this advice isn't helpful if you actually need to do things this way for some reason.
Related
I am an Network Engineer Apprentice and have been set a task that will copy a file from a server directory and use FTP to copy it to another location. Essentially these are the steps that I would take:
Log in to NMS (Linux Box)
Change directory to /usr/lib/rancid/bin/clogin
Sudo rancid
clogin (IP Address of SVC)
change directory to disk:/ftp/reports/rogueaps
use FTP to copy the last created file to (IP Address)
As you can tell I am very new to this and only have about 2 months of experience in Networking and know very little about coding and scripting. There is no rush to get this created and time is on my side.
This script will need to run once a day. I do not expect anyone to create the script for me but pointing me in the right direction would be appreciated. I am also able to use any language of my choice and I think python would be neat to learn.
Thank you
In general, you should try to avoid FTP. If you can scp to the remote host, that would certainly be preferable.
If you need to stick to ftp, and if you have lftp as client available, you would probably do something like this:
#!/bin/bash
nwd=/ftp/reports/rogueaps
user=rancid
passwd=VeRySecR3t
host=ip_of_SVC
cd /usr/lib/rancid/bin/clogin
lftp -u $user,$passwd $host <<EOF
cd $nwd
put $f
EOF
and put that in the crontab for the user rancid.
This is of course just a pointer to what you could do. In general, it is a bad idea to put passwords directly in the script. If you're courageous, you might try to get the uid/password from the .cloginrc in your script.
If that is not what you're looking for, you should look into expect. Clogin is basically an expect script that does some logins.
I created the simple python script using pexpect, created one spwan process using
CurrentCommand = "ssh " + serverRootUserName + "#" + serverHostName
child = pexpect.spawn(CurrentCommand)
Now I am running some command like ls-a or "find /opt/license/ -name '*.xml'"
using code
child.run(mycommand)
it works fine if running from Pycharm but if running from terminal it is not working it is not able to find any file, I think it is looking into my local system.
Can anyone suggest me something. Thanks
As a suggestion, have a look at the paramiko library (or fabric, which uses it, but has a specific purpose), as this is a python interface to ssh. It might make your code a bit better and more resilient against bugs or attacks.
However, I think the issue comes from your use of run.
This function runs the given command; waits for it to finish; then returns all output as a string. STDERR is included in output. If the full path to the command is not given then the path is searched.
What you should look at is 'expect'. I.e. your spawn with spawn then you should use expect to wait for that to get to an appropiate point (such as connected, terminal ready after motd pushed etc (because ouy might have to put a username and password in etc).
Then you want to run sendline to send a line to the program. See the example:
http://pexpect.readthedocs.io/en/latest/overview.html
Hope that helps, and seriously, have a look at paramiko ;)
I am trying to use perl to SSH in to a machine and issue a few commands...
my $ssh = Net::SSH::Perl->new($host);
$ssh->login($user,$pass);
my($stdout, $sterr, $exit) = $ssh->cmd($cmd);
print "$stdout \n"
This is the general idea, but I am still stuck at the prompt for the password. I have also attempted to use python, and also can not get past the prompt for password. Expect, on the other hand, handles the password just fine. Does anyone have any idea what would cause this?
Edit: additional info
I am using putty to a linux machine and then ssh into numerous more linux machines. Using the perl code above, the user name gets set correctly, but I end up having to manually entering the password each time.
use strict;
use warnings;
use Expect;
$exp= Expect->spawn("ssh $host -l $user");
sleep(1);
$exp->expect($timeout,"Password:");
$exp->send("$pass\r");
$exp->expect($timeout,-re,'>');
$exp->send("ls -l\r");
$exp->expect($timeout,-re,'>');
$exp->send("mkdir aDir\r");
$exp->expect($timeout,-re,'>');
$exp->send("chmod 777 aDir\r");
$exp->expect($timeout,-re,'>');
$exp->send("exit\r");
left out variable declarations for obvious reasons... Not exact answer to question but a viable work around using only the "Expect Module".
Because I am unable to find a library that does the following I started heading out to write my own. I'm unable to find a solution for some problems, though, and hope that here maybe someone has a suggestion.
What I want is this. I send a normal shell command like ls -al <some path> and I want its output (stdout and stderr) in the same fashion and order as it would appear in my terminal emulator when writing that command. The catch is, that I don't want to run this shell command on the computer I'm currently using, but remotely via ssh or serial connection. To put it another way, when calling ls -al <some path> 2>&1 >/tmp/out I want to remotely receive the contents of /tmp/out without interruption or changes.
The problem is, with the serial connection always, with the ssh connection depending on your choice of library, that you get terminal command chars like \x1b[K mixed into your output. I am currently unable to find what exactly is creating these commands, why nothing is consuming them already, and I also don't know how I would go about consuming all of them myself (there are a lot, naive approaches won't work).
Why is it a problem to get special characters in your output? Well often you want to compare in your python code if the output has a string ala if expected_output == output, or at least use regular expressions. But there is nothing regular about when and why these characters appear. Sometimes a very simple command like ls -al <something> might result in the whole ssh connection breaking down (supposely because of these characters, but at least for sure because I don't know enough about all this to even understand what's the problem).
How would you go about solving the ultimate goal of sending commands remotely and receiving their output? How would you solve one of the mentioned subproblems (ssh connection that speaks to me like I would be a terminal, consuming randomly appearing special characters without interpreting them, etc)?
PS: There are many things I've already tried, but while writing I found them too many to list them all here. Nothing led to a desired end result, though. This really is a quite complex problem, especially because there seem to be things involved that are not traceable (like how many (pseudo-)terminals are actually involved) and others were never documented (some of the terminal handling seems to come from a time, where an actual typewriter was connected to the computer).
You already have this type of library.Try
Pexpect.
You just need to spawn a pexpect child by making a ssh connection to the computer you want to make connection to.Then you can send commands and see ouput using .before functionality.
Example:
child = pexpect.spawn('ssh admin#192.168.33.40')
child.expect ('Password:')
child.sendline (mypassword)
child.expect('#') # or expect `$`.
child.sendline('<your command>')
child.expect('#')
print child.before
Ref:http://pexpect.sourceforge.net/pexpect.html
P.S there's also Paramiko for the same though i havent used it.
I'm trying to write a python script that can make my computer associate to a wireless access point, given the name as a string. For example, I might specify I want to connect to linksys, and my script would cause the computer to do that.
I looked at this question, but wasn't able to understand what to do from looking at the links provided.
Can somebody point me in the right direction?
I decided to take Paulo's suggestion and try using Powershell/the command line. I found an article about connecting to a network via the command line.
From the command line, you can do:
netsh wlan connect <profile-name> [name=<ssid-name>]
...where the name=<ssid-name> part is optional and is necessarily only if the profile contains multiple ssids.
However, it looks like the profile must already exist on the machine in order for the command line stuff to work. I did find a forum post on programatically creating a profile, but I didn't feel like canvassing through it.
If the profile name already exists, then from Python you can do something similar to the following:
import subprocess
def connect_to_network(name):
process = subprocess.Popen(
'netsh wlan connect {0}'.format(name),
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
stdout, stderr = process.communicate()
# Return `True` if we were able to successfully connect
return 'Connection request was completed successfully' in stdout
It's an imperfect solution, and I'm not entirely sure if it'll work in every case, but it did work for my particular case. I thought I'd post what I came up with in case somebody else wants to try modifying it to make it better.
The answer you linked talks about calling low level C functions from the Windows API. Fiddling with low level stuff makes my brain hurt.
There is a .Net wrapper around the native C calls, you can use this higher level API directly from IronPython. Unfortunately it is not well documented, but looking at the C# sample and digging over the sources should be easier than calling the underlying API. This is a very windows-centric solution, so you may be better served by powershell.
I've written a Python CLI tool for controlling Wi-Fi over command line interface. There's a library in this project, and it should fit your requirement.
https://github.com/changyuheng/pywinwifi
There's another standalone library but I've never tried it.
https://github.com/reedcourty/pynetsh