20

I am writing a program in python on Ubuntu. In that program I am trying to print a message after completing a task "Delete a File" on Remote machine (RaspberryPi), connected to network.

But In actual practice, print command is not waiting till completion of task on remote machine.

Can anybody guide me on how do I do that? My Coding is given below

import paramiko

# Connection with remote machine
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect('192.168.2.34', username='pi', password='raspberry')

filename   = 'fahad.txt'
filedelete ='rm ' + filename
stdin, stdout, stderr = client.exec_command(filedelete)
print ("File Deleted")
client.close()
Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
Irfan Ghaffar7
  • 1,143
  • 4
  • 11
  • 30

2 Answers2

56

This is indeed a duplicate of paramiko SSH exec_command(shell script) returns before completion, but the answer there is not terribly detailed. So...

As you noticed, exec_command is a non-blocking call. So you have to wait for completion of the remote command by using either:

  • Channel.exit_status_ready if you want a non-blocking check of the command completion (i.e.: pooling)
  • Channel.recv_exit_status if you want to block until the command completion (and get back the exit status — an exit status of 0 means normal completion).

In your particular case, you need the later:

stdin, stdout, stderr = client.exec_command(filedelete)  # Non-blocking call
exit_status = stdout.channel.recv_exit_status()          # Blocking call
if exit_status == 0:
    print ("File Deleted")
else:
    print("Error", exit_status)
client.close()
Community
  • 1
  • 1
Sylvain Leroux
  • 50,096
  • 7
  • 103
  • 125
  • 1
    The answer is in principle correct. Except that the actual implementation cannot be this simple, as it would deadlock if the command output is sufficiently large. See [Paramiko ssh die/hang with big output](https://stackoverflow.com/q/31625788/850848). – Martin Prikryl Apr 06 '21 at 07:42
6

In addition to doing what Sylvian Leroux suggests:

If your commands involve running a bash script that needs to keep running after paramiko closes the ssh session (every time you send a command this happens) use:

nohup ./my_bash_script.sh >/dev/null 2>&1.

nohup tells the system that this process should ignore the "hang up" signal received when the ssh session is closed.

>/dev/null 2>&1 redirects the output. This is necessary because in some situations control will not be given back to your python script until an output is received.

To run command line applications like "stress" and "vlc" and keep them running after you return, the only solution I have found is to put your commands in a bash script followed by a & or &>/dev/null then call that bash script with paramiko using the method I mention in the previous paragraph.

This seems a bit "hacky" but it is the only way I have found after days of searching.

Amr
  • 411
  • 6
  • 21
  • 1
    This doesn't really answer the question, however, I believe it provides some useful insight into how ssh/linux work. – JerodG Dec 20 '17 at 15:21