47

Drush commands not executing using Paramiko

I posted the above question regarding a persistent error message that I receive using Paramiko. I do not think it is related to my next question, but it might be.

I can successfully connect to my server via SSH using Paramiko. I can execute commands like ls or pwd. What I can't seem to do is change directories. I can send the command "cd .." for example, but when I follow up with "pwd" it shows that I haven't changed directories. It just lists the initial directory I am in when I log in.

>>> stdin, stdout, stderr = myssh.exec_command("pwd")
>>> stdout.readlines()
['/big/dom/home/myid\n']
>>> stdin, stdout, stderr = myssh.exec_command("cd ../")
>>> stdout.readlines()
[]
>>> stdin, stdout, stderr = myssh.exec_command("pwd")
>>> stdout.readlines()
['/big/dom/home/myid\n']
>>>

Am I misunderstanding what is going on here? Should I not be able to change directories? Or if I can, should I be doing it in some other way than using exec_command?

jww
  • 97,681
  • 90
  • 411
  • 885
Mike Ryan
  • 2,359
  • 2
  • 17
  • 24
  • 1
    Possible duplicate of [How do you execute multiple commands in a single session in Paramiko? (Python)](https://stackoverflow.com/questions/6203653/how-do-you-execute-multiple-commands-in-a-single-session-in-paramiko-python) – tripleee Jun 27 '17 at 09:46

4 Answers4

55

This guy had it figured out: http://www.vertigrated.com/blog/2010/02/python-remote-ssh-with-paramiko/

You just have to send multiple commands with one exec_command, such as:

myssh.exec_command('cd ..; pwd')

Then stdout.readlines() will return the directory that you changed to.

falsetru
  • 357,413
  • 63
  • 732
  • 636
Mike Ryan
  • 2,359
  • 2
  • 17
  • 24
  • 3
    I tried to send multiple commands with one exec_command like "ssh.exec_command('cd /usr/soumya/PGMS/;pwd')" , but its not working. Hence i tried to print the stderr output and it is as follows: ['bash: line 0: cd: /usr/soumya/PGMS/: No such file or directory\n']. The output shows its still in root. "['/root\n']" – s.patra Jun 02 '17 at 16:59
10

Well paramiko creates an instance of shell and all the commands that you wish to execute in paramiko have to be given in that instance of shell only.

For example: Let us say I have some folder in the directory I am in.

folder1
folder2
folder3

Now if I want to cd into folder 1 and make a directory there what I would do is:

ssh.exec_command('cd folder1;mkdir folder4')

if you write it like:

ssh.exec_command('cd folder1')
ssh.exec_command('mkdir folder4')

you would get the result like

folder1
folder2
folder3
folder4

as those were two different instances of the shell and would be independent in their function.

Aklank Jain
  • 1,002
  • 1
  • 13
  • 21
  • This is a very clear explanation that seems to be accurate based on what I've read from the docs. +1. – bob Dec 02 '19 at 18:04
7

As of version 2.6, if you use the SFTPClient, the method to change directories is sftp = myssh.open_sftp() sftp.chdir('path/to/directory')

jarriett
  • 1,219
  • 12
  • 7
  • This seems like the correct answer for a sufficiently modern version of Paramiko. – jww Jul 01 '19 at 09:17
  • 1
    What if you want to use SSHClient instead of SFTPClient? This answer only seems to apply to the latter. If that's the case, could you edit the answer to make this caveat more explicit? – bob Dec 02 '19 at 18:03
  • 1
    Thanks @bob, you're absolutely right. I've edited the answer to be more specific. – jarriett Dec 06 '19 at 22:18
2

A bit late with this one, but its possible to 'invoke_shell' and write to the standard input through a file.

Please see: https://stackoverflow.com/a/6203877/1861353

Seems a little bit heavyweight since you can just ';'.join(cmdlist) and send to the exec_command.

Community
  • 1
  • 1
Kevin R.
  • 336
  • 4
  • 14