I am using below code to execute commands on a remote machine,
import paramiko
import os
dssh = paramiko.SSHClient()
dssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
dssh.connect('192.168.1.5', username='root', password='asdfghhh')
import os
stdin, stdout, stderr = dssh.exec_command('ls')
print stdout.read()
stdin, stdout, stderr = dssh.exec_command('ifconfig')
print stdout.read()
stdin, stdout, stderr = dssh.exec_command('ps')
print stdout.read()
dssh.close()
when I execute the program, Its able to show the ls and ps as well as other commands output.
however ifconfig o/p is not observed.
any idea how to solve this problems?
Thanks in advance...
Your server may be discriminating between interactive and non-interactive SSH sessions, running different startup scripts for the different sessions. Try running echo $PATH on the remote host through the paramiko SSH session and a regular interactive one and compare the outputs.
For a workaround you can do a which ifconfig on the remote server in an interactive session to get the absolute path and use that in your paramiko command.
stdin, stdout, stderr = dssh.exec_command('/abs/path/to/ifconfig')
NOTE
On one of my hosts the result of echo $PATH from the paramiko SSH client was /usr/bin:/bin, while in an interactive session it was /usr/local/sbin:/usr/sbin:/usr/bin:/sbin:/bin, and ifconfig was indeed located in /usr/sbin, i.e. outside the path of the paramiko session.
To get the output for certain application binaries you must use the flag: get_pty=True
I'm still looking for the reason it happens for some commands, it's for me unknown yet. However the way I found to workaround this problem is shown in the example below:
import paramiko
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('10.2.0.230', username='ibmsys1', password='passw0rd', timeout=5)
stdin, stdout, stderr = ssh.exec_command('/sbin/ifconfig', timeout=3, get_pty=True)
print stdout.read()
Usually I would run:
#stdin, stdout, stderr = ssh.exec_command('/sbin/ifconfig')
in my example, I've just added 2 new flags, timeout=3 and get_pty=True
This solved my problem. The timeout flag is not related, however I always use it as good practice. The point here is the use of the get_pty=True
PS. I would recommend do not trust on the system $PATH, always input the full path for the application to be run, e.g: /usr/bin/my_binary or in your case /sbin/ifconfig
I hope this may help you to workaround the problem.
Good luck!
Related
What is the way to run a .bat (or Python) script on a remote Windows server 2016? SSH server is installed and works correctly.
I tried using Paramiko, but it didn't bring any result:
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('ip', username='root', password='pass')
ssh_stdin, ssh_stdout, ssh_stder = ssh.exec_command('C:/Users/Administrator/Desktop/main/videos/uniq.bat')
What am I doing wrong? The script does not run. However, if you run it manually, it works well.
The batch file is:
FOR /F "tokens=*" %%G IN ('dir /b *.mp4') DO ffmpeg -i "%%G" -vf noise=alls=1:allf=t "%%~nG_1.mp4"
The SSHClient.exec_command only starts an execution of the command. If you do not wait for it to complete and immediately kill the session, the command is killed along with it.
The most trivial way to wait for command to complete is reading its output to the end:
stdin, stdout, stderr = ssh.exec_command(command)
stdout.channel.set_combine_stderr(True)
output = stdout.readlines()
If this won't fix the problem on its own, it will at least collect any error output to help you identifying the (other) problem.
I have to monitor 8 to 9 servers. I am thinking of creating a python script that will create a menu to login to any servers and after using ssh to login to the server, can I be able to execute commands in the server as the 'user' specified in the ssh. Please see the command below in python. I am importing 'os' to execute the bash commands.
server_login = "ssh {}#{}".format('user_name','10.111.0.10')
os.system(server_login)
you can install paramiko for this
pip install paramiko
then the script can be like
import paramiko
host = "google.com"
port = 22
username = "user"
password = "Pass"
command = "ls"
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(host, port, username, password)
stdin, stdout, stderr = ssh.exec_command(command)
lines = stdout.readlines()
print(lines)
If paramiko isn't your style, I can think of two other ways to do this:
run the command: ssh <user>#<host> <command> for every command via os.system calls. This gets rather cumbersome when you're using passwords for SSH instead of keys.
run ssh <user>#<host> with the subprocess library instead so you can get access to stdin and stdout and run multiple commands in the session
import subprocess
p = subprocess.Popen(['ssh','root#example.com'], stdout=PIPE, stdin=PIPE)
p.stdin.write("ls\n")
print(p.stdout.read())
I am trying to execute a command in remote system as a root user. Since remote root login is disabled, we need to connect as a admin user and switch to root and execute the command. how can we achieve this in python.
connect to remote system as a admin user.
switch to root user
execute commad as a root user(sudo permission not available)
disconnect from the remote system.
.
#!/usr/bin/python2
import time
import paramiko
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('x.x.x.x', port=22, username='admin', password='pass')
stdin, stdout, stderr = ssh.exec_command('su')
time.sleep(0.1) # some enviroment maybe need this.
stdin.write('root_password_goes_here\n')
#[ add extra code here to execute a command ]
stdin.flush()
print (stdout.readlines())
ssh.close()
https://unix.stackexchange.com/questions/436013/ssh-login-as-user-and-change-to-root-without-sudo
i tried the above code but the command is always executed as a admin not as a root user.
Regards,
Ram
Instead of
stdin, stdout, stderr = ssh.exec_command('su')
try ,
stdin, stdout, stderr = ssh.exec_command('/bin/su root -c "smartctl -a /dev/sda > /tmp/smartctl_output"', get_pty=True)
su allows to run commands with a substitute user and group ID. When called without arguments, su defaults to running an interactive shell as root.
This question already has an answer here:
Execute (sub)commands in secondary shell/command on SSH server in Python Paramiko
(1 answer)
Closed 3 years ago.
My goal is to be able to SSH into a device, execute CLI command which will take me to another Shell where I can enter in my commands. Currently, I am able to successfully SSH into a device, but cannot figure out how to get to that secondary shell with the CLI. My code below
import datetime, logging, os, paramiko, re, scp, sys, time, socket, logging
SSH = paramiko.SSHClient()
SSH.set_missing_host_key_policy(paramiko.AutoAddPolicy())
SSH.connect(server, username=usr, password=password, port=22, timeout=2)
print('successful ssh')
stdin, stdout, stderr = SSH.exec_command('cli console',bufsize=2)
# inBuf = stdout.readlines()
# for line in inBuf:
# print(line.strip('\n'))
SSH.close()
My initial assumption is that after executing the cli to get into the shell console, I would be able to just simply execute whatever command I want but that is not the case. Any help would be appreciated
Write the commands that you want to execute in the subshell to the stdin:
stdin.write('command\n')
stdin.flush()
What I actually tried to do:
Using a python script to start a nc(netcat) on a remote host using SSH. This netcat should listen for incoming TCP connections. It could be possible that no one wants to connect to the remote host so the netcat process have to be killed.
My first idea was using the PID of the nc process on the remote host and execute a simple kill [PID] command. But I was not able to get the process id from the nc process on the remote host.
What I have tried so far was using paramiko and sshpass.
My paramiko code:
import os, sys, paramiko
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(host, username=user, password=password)
stdin, stdout, stderr = ssh.exec_command("nc -l -p"+port+"&")
print stdout.readlines()
Using sshpass:
sshProcess = subprocess.Popen(["sshpass", "-p", password, "ssh", user+"#"+hostaddress, "nc", "-l", "-p", str(destPort),"&"], stdout=subprocess.PIPE, stdin=None)
print sshProcess.stdout.read()
I tried the sshpass approach on the normal linux terminal and the pid of the netcat process was returned. But trying both approaches in a python script had the same result: the whole script was blocked instead of returning the PID. If I do not try to read the output -- that means deleting the stdout.readlines() or sshProcess.stdout.read() -- the scripts are not blocked but I also do not get the PID of the netcat process on the remote host.
I am working on a Linux machine and the remote host also runs Linux.
Remove "&" to execute nc synchronously with ssh -t then to kill nc just kill the subprocess (p.terminate()).
See how to stop reading the subprocess stdout on timeout.