I am trying to execute some command to remote machine through python
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(SERVER_IP, username='root', password='xxxxx')
stdin, stdout, stderr = ssh.exec_command(
"tar -C /home -xzf /home/Tests.tar.gz;dos2unix /home/Tests/run.py;chmod +x /home/Tests/run.py;/home/Tests/run.py>/home/Tests/log.txt"
)
it seems the last command /home/Tests/run.py>/home/Tests/log.txt is not working the log.txt is not having the values, the same works well if I do /home/Tests/run.py>/home/Tests/log.txt on remote machine terminal.
How to resolve it ?
Thanks in advance
You are not transporting the client to session like so :
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(SERVER_IP, username='root', password='xxxxx')
#note the next line you are missing
ssh_session = ssh.get_transport().open_session()
Then (after the declaration of ssh_session) you may use ssh_session.exec_command(. . .).
Try that see if it works.
To make sure your paramiko code is working and the connection is being made, try something simple like
stdin, stdout, stderr = ssh.exec_command("hostname")
and make sure that stdin contains what you expect. Then have a go at debugging the command you're executing remotely:
$ tar -C /home -xzf /home/Tests.tar.gz
$ dos2unix /home/Tests/run.py
$ chmod +x /home/Tests/run.py
$ /home/Tests/run.py > /home/Tests/log.txt
If you run code on the remove machine through a regular ssh connection it must perform as you expect it to if you want it to also work over paramiko.
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 a shell script stored on my local machine. The script needs arguments as below:
#!/bin/bash
echo $1
echo $2
I need to run this script on a remote machine (without copying the script on the remote machine). I am using Python's Paramiko module to run the script and can invoke on the remote server without any issue.
The problem is I am not able to pass the two arguments to the remote server. Here is the snippet from my python code to execute the local script on the remote server:
with open("test.sh", "r") as f:
mymodule = f.read()
c = paramiko.SSHClient()
k = paramiko.RSAKey.from_private_key(private_key_str)
c.set_missing_host_key_policy(paramiko.AutoAddPolicy())
c.connect( hostname = "hostname", username = "user", pkey = k )
stdin, stdout, stderr = c.exec_command("/bin/bash - <<EOF\n{s}\nEOF".format(s=mymodule))
With bash I can simply use the below command:
ssh -i key user#IP bash -s < test.sh "$var1" "$var2"
Can someone help me with how to pass the two arguments to the remote server using Python?
Do the same, what you are doing in the bash:
command = "/bin/bash -s {v1} {v2}".format(v1=var1, v2=var2)
stdin, stdout, stderr = c.exec_command(command)
stdin.write(mymodule)
stdin.close()
If you prefer the heredoc syntax, you need to use the single quotes, if you want the argument to be expanded:
command = "/bin/bash -s {v1} {v2} <<'EOF'\n{s}\nEOF".format(v1=var1,v2=var1,s=mymodule)
stdin, stdout, stderr = c.exec_command(command)
The same way as you would have to use the quotes in the bash:
ssh -i key user#IP bash -s "$var1" "$var2" <<'EOF'
echo $1
echo $2
EOF
Though as you have the script in a variable in your Python code, why don't you just modify the script itself? That would be way more straightforward, imo.
Obligatory warning: Do not use AutoAddPolicy – You are losing a protection against MITM attacks by doing so. For a correct solution, see Paramiko "Unknown Server".
I am trying to do a ssh to my local machine - 127.0.0.1, which works fine.
Next, I am trying to run two commands through ssh client. However, I see that the next command fails. I could see that my tap device is created. However, the tap device is not turned up. Here is my code. I tried the ifconfig and it works fine.
However, it is the sudo commands that is creating a problem.
self.serverName is 127.0.0.1
def configure_tap_iface(self):
ssh = paramiko.SSHClient()
print('SSH on to PC')
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(self.serverName, username='zebra', password='Zebra#2018')
stdin, stdout, stderr = ssh.exec_command('ifconfig')
#print(stdout.read())
session = ssh.get_transport().open_session()
session.get_pty()
session.exec_command('sudo ip address add 192.168.0.1/24 dev cloud_tap && sudo ip link set cloud_tap up')
session.close()
time.sleep(3)
ssh.close()
You can use sudo sh -c 'commands' to run multiple shell commands in a single sudo invocation.
session.exec_command("sudo sh -c 'ip address add 192.168.0.1/24 dev cloud_tap && ip link set cloud_tap up'")
I can't read a perl script command out from shh. I can reading things like ifconfig, pwd but I installed an application written in perl but cant read out from its command from another server when using remote ssh. Tried a lot of steps
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname=sys_ip,
port=22,
username=sys_username,
password=sys_password)
cmd = "cd /; export TERM=${TERM:-dumb}; commandforperlscript"
I get no output and no errors.
My scenario is I need to login to a remote machine and then do a sudo to another account like (sudo su anotheract) and then run the other required command.
But I am able to successfully connect to remote machine using below script. But the scripts hangs in the line where I am executing the sudo command(sudo su anotheract)
Can you please help me find the fix for this code?
import paramiko
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(
paramiko.AutoAddPolicy())
ssh.connect(hostname='XX.XXX.XX.XX',port=22, username='myname',password='XXXXX')
ssh.exec_command=("sudo su anotheract")
stdout,stdin,stderr=ssh.exec_command("java -jar /usr/share/XXX/LogR.jar")
print stdout.readlines()
One (not very safe) way to do it is to pipe the password in. The caveat is that the user that you are using to connect to the box using paramiko should have sudo rights.
For example:
supass = 'some_pass'
stdout, stdin, stderr = ssh.exec_command('echo %s | sudo -S anotheract' % supass)
Again, this is not a very safe implementation but gets the job done in a jiffy.
import pxssh
ssh = pxssh.pxssh()
ssh.login('host', 'user', 'password')
ssh.sendline("sudo su anotheract")
ssh.prompt('yourrootpassword')
And in paramiko on most linux systems you cant do sudo commands thats because sudo expect commands from tty and then it isnt raise exception, but you can try method invokeshell, but I used paramiko many years ago I dont remember what was been wrong with it. If you want send various commands on shell you could use pxssh.
It can hangen because sudo waits for password. Try to add NOPASSWD: statement to the /etc/sudoers.
user ALL = NOPASSWD: /bin/true
Also it is impossible to change user using su and then continue do to something after su is finished. When su is finished, you are back to your original shell of the original user.
So you need to run all commands with sudo:
stdout,stdin,stderr = ssh.exec_command=("sudo -u anotheract java -jar /usr/share/XXX/LogR.jar")