On Fri, Mar 27, 2009 at 2:22 PM, James <rocketmonk...@gmail.com> wrote:
> I've seen other posts about this, but no answers.  My desire is to run
> an SSH session in a scripted fashion.  As one example, I would like to
> be able to do this:
>
> client = paramiko.SSHClient()
> client.connect(...)
> client.exec_command('cd directory_name')
> client.exec_command('ls')
>
> However, due to the way exec_command() works it automatically creates
> a new session/channel every time.  That means the results of the first
> command (changing the working directory) does not affect the second
> command (so the 'ls' wont give me the right directory listings).
>
> So the next step is to look at the transport & channel objects.  Now I
> have this:
>
> transport = client.get_transport()
> session = transport.open_session()
> session.exec_command('cd directory_name')
> session.exec_command('ls')
>
> However, in this case I get an error because of this:
> "When the command finishes executing, the channel will be closed and
> can't be reused. You must open a new channel if you wish to execute
> another command."
>
> I know I can do something like this:
> client.exec_command('cd directory_name; ls')
>
> However, that means I cannot use the results of one command to
> influence another.  For example, if I wanted to 'ls file_name' to test
> if a file existed, then do different things depending on if it was
> there or not, I wouldn't be able to.
>

Since you're running the command in a remote shell, you need to rely
on that shell to handle some aspects of your program logic. Let the
remote shell determine if the file exists, or whether the 'cd' was
completed successfully. Tthe commands are being executed
asynchronously, so you have no easy way to determine what's going on.
Did the command complete with no output? Is it still running?


> So my question is this: how do I execute multiple commands on a single
> session/channel?  I've seen others ask the same question, and so it
> seems like there should be an obvious way to do this that I just don't
> understand.
>

The best way to handle this is usually with exec_command, because then
you *can* tell if the command is running, and it's exit status.
Bundling the commands you want into small scripts may work well.

> Please note: I do not want an interactive shell, unless that is the
> preferred way for python to script commands in this scenario.  I don't
> want user input from the local computer (which is what I'm assuming
> the invoke_shell() command is intended for).

If you want a shell where you can send a command, read the result, and
send another command, that is an interactive shell.
To get a shell without a terminal, command prompt, login, etc; you
could exec_command ' bash -s'. Then you could send commands over the
channel, and read the output.

In [5]: t = client.get_transport()
In [6]: chan = t.open_session()
In [7]: chan.exec_command('bash -s')
In [8]: chan.send_ready()
Out[8]: True
In [9]: chan.send('pwd\n')
Out[9]: 4
In [10]: chan.recv_ready()
Out[10]: True
In [11]: chan.recv(1024)
Out[11]: '/home/jbardin\n'
In [12]: chan.send('cd Desktop\n')
Out[12]: 11
In [13]: chan.send_ready()
Out[13]: True
In [14]: chan.send('pwd\n')
Out[14]: 4
In [15]: chan.recv_ready()
Out[15]: True
In [16]: chan.recv(1024)
Out[16]: '/home/jbardin/Desktop\n'


> I don't want to run 'cd
> directory_name; ls; cmd; cmd; cmd;', since as I stated above that is
> not sufficient for what I need.  I would also like to avoid doing
> adding 'ls directory_name' in front of every single command, since
> that would also have to apply to things like environment variables,
> etc.  I'm truly looking for a way to execute multiple commands on a
> single channel.
>

Because you're executing code on the remote machine, I highly
recommend moving the logic there as well. There are also synchronous
remote execution mechanisms like xmlrpc. You could always tunnel the
xmlrpc socket over ssh for the security.

-jim

_______________________________________________
paramiko mailing list
paramiko@lag.net
http://www.lag.net/cgi-bin/mailman/listinfo/paramiko

Reply via email to