开发者

Using SSH in python

开发者 https://www.devze.com 2023-04-09 16:29 出处:网络
I need to connect with other server via SSH using Python开发者_开发技巧, execute few comands and assign result of each command to differrent variables.

I need to connect with other server via SSH using Python开发者_开发技巧, execute few comands and assign result of each command to differrent variables.

What is the simplest way to do it?

I've tried SSHController, but I think, I've screwed up something with prompt, and the script is waiting for it endlessly.

I'll be so grateful for any examples.


There are a number of ways to use SSH from within Python. The general approaches are:

  • Call the local ssh binary using subprocess.Popen() or similar (suitable only for gathering the results in batch)
  • Call and control the local ssh binary using pexpect or a similar pty (psuedo-TTY) process control mechanism (for spawning and interacting with a process in a terminal session in an automated manner)
  • Use a Python module/library, like Paramiko or Twisted conch, which implements SSH protocols (either directly in native Python, or by providing bindings to some underlying shared library ... .so or DLL).

SSHController is in the second of these broad categories. My own humble utility, classh is in the first category.

Your question suggests that you might be best served by exploring Paramiko because it sounds like you want to set local variable state based on the results from remote process execution. I'm guessing that you don't want any chance of conflating any sort of local terminal output or error messages with the remote command's results.

In other words it sounds like you want to use SSH as an API rather than ssh as a command utility. This is an essential distinction.

The ssh command tries to be as transparent as the UNIX (and analogous MS Windows, etc) environments allow. ssh opens a connection to the remote system and creates a number of channels over which remote job execution communicates. So the local ssh stdout will be from the remote commands' stdout and the local ssh stderr will be a mixture of the remote's stderr and any of the ssh command's own error messages (and other output, such as the debugging information you'd see from adding the -v, --verbose options to your ssh invocation). Similarly the ssh command's exit status will, normally, reflect the exit status from the remote shell. However it may also be the local ssh process' own exit code from a local error --- which, in my experience, seems to always be value 255. I know of no way that you could distinguish between a remote command's exit value of 255 vs. an "abend" (abnormal process end) from the local process --- and I suspect that there is not any portable, standard way to do so).

My point here is that using the ssh command from within your code will, necessarily, preclude you from separating the output from local processes (the ssh binary itself, and perhaps, depending on how you're executing it, a local shell for that) and those which emanated from the remote process (and perhaps the shell in which the intended remote process is running). ssh is not an API.

On the other hand if you use something like Paramiko then you establish a session over the SSH protocol and you can use, and re-use that to execute commands, transfer files, perform some other filesystem functions, and create tunnels.

In that case you create an SSHClient instance and call its .exec_command() method for each command you which to execute on the remote host. This is conceptually similar to making a local function call ... it will raise an exception if the command could not be executed for any reason ... and any results you get from its stdout or stderr cannot be conflated with possible output from any intermediary processes (such as the ssh binary ... which isn't being executed at all in this case).

That's why I'm recommending this approach. It sounds like you want to execute several separate commands on each remote target in a way that obviates the possible complications arising from running them all in a single call to the ssh utility and without the complications and performance overhead of making multiple calls to ssh. It sounds like your code will be much simpler and more robust if you can establish a session and use that as an API.

0

精彩评论

暂无评论...
验证码 换一张
取 消