我正在尝试通过具有良好资源的远程服务器执行Python脚本(机器学习)。
而且我试图使用Paramiko库在本地环境中调用远程Python代码。 (我将命令发送到远程服务器,该远程服务器将执行该命令)
在本地环境中的代码如下:
cli = paramiko.SSHClient()
cli.set_missing_host_key_policy(paramiko.AutoAddPolicy)
server = config['ip']
user = 'ubuntu'
pwd = config['pw']
cli.connect(server, username=user, password=pwd)
command="python my_code.py"
stdin, stdout, stderr = cli.exec_command(command)
我通过上述代码将命令发送到远程服务器。但是,那无济于事。
当命令是基本linux命令(ex,ls -al,cd,pwd ...)时。
但是远程服务器的单元格无法识别其他命令,例如Python〜.py,Conda激活,PIP安装...
我的奇怪是,当我直接连接到远程服务器的Shell时,这些命令可用。请参阅下文:
我猜我直接连接时打开的bash与帕拉马科操作的bash不同。我该如何处理这个问题?
真诚地感谢
I'm trying to execute a python script(machine learning) via remote server which has good resources.
And I'm trying to call remote python code in local environment with Paramiko library. (I send command to remote server, and that remote server will execute that command)
code in local environment is below:
cli = paramiko.SSHClient()
cli.set_missing_host_key_policy(paramiko.AutoAddPolicy)
server = config['ip']
user = 'ubuntu'
pwd = config['pw']
cli.connect(server, username=user, password=pwd)
command="python my_code.py"
stdin, stdout, stderr = cli.exec_command(command)
I send a command to remote server via above code. But, that doesn't work.
When the command is basic linux command (ex, ls -al, cd, pwd ...) those work.
But the remote server's cell does not recognize other commands like, python ~.py, conda activate, pip install...
My wonder is that, those commands are available when I directly connect to remote server's shell. see below:


I guess the bash that is opened when I directly connect is different from the bash that Paramiko handles. How can I handles this problem?
thanks sincerely
发布评论
评论(1)
问题的来源:
根据您连接到遥控器(或本地)机器的方式,有不同类型的外壳会话可以运行。这些不同的外壳类型“源”(或执行)不同的配置文件启动时。当您从终端进入远程服务器时,您将连接到所谓的“ Interactive login shell ” - 它的“交互式”是因为您可以交互式运行和中断命令,并且是“登录外壳”,因为它是登录后启动的第一个外壳在 1 中。
Interactive bash登录shells source 各种文件 (除其他外)通过将包含可执行文件的目录添加到
$ path
中,使您可以使用其他命令。您提到了conda
,例如 - 当您安装conda
时,它会自动将某些代码添加到您的.bash_profile
以使其在该文件为来源,这是用于交互式登录外壳 2 。但是,当您以paramiko的方式发送SSH命令时,默认情况下,该命令在A non Interactive( non> non -login)shell中调用。在这种情况下,您的配置文件是不是来源 3 ,这就是为什么您期望可用的命令的原因。
如何修复它:
最简单的方法是简单地更改
cli.exec_command(< command>)
cli.exec_command('/bin/bin/bash/bash -lc“< lt; command>” ')
。-l </code> flag
原因
bash 表现得好像是在登录外壳中调用的,这意味着它将从终端中ssh中摘取所有相同的配置文件。
如果您需要交互式外壳,则可以使用
cli.get_pty()
和cli.invoke_shell()
,但这对于仅运行Python脚本并不需要。
最后,我强烈建议您查看
spurplus
。它建在 paramiko 的顶部,除了 易于使用之外,还增加了一些不错的功能。1 这对于Linux系统是正确的。在MacOS上,您启动的随后的交互式外壳也是登录外壳。
2 也有交互式非login shells,而是源于
.bashrc
。同样,对于非Linux机器,其中一些略有不同,以及Zsh。 //www.gnu.org/software/bash/manual/html_node/bash-startup-files.html“ rel =” nofollow noreferrer“>
$ bash_env
文件。Source of the issue:
There are different types of shell sessions that get run depending on how you connect to a remote (or local) machine. These different shell types "source" (or execute) different configuration files when they are launched. When you ssh into the remote server from your terminal, you connect to what's called an "interactive login shell"—it's "interactive" because you can interactively run and interrupt commands, and it's a "login shell" because it's the first shell launched after you logged in1.
Interactive Bash login shells source various files that typically (among other things) make additional commands available to you by adding directories containing executables to your
$PATH
. You mentionedconda
, for example—when you installconda
, it automatically adds some code to your.bash_profile
to make it available when that file is sourced, which it is for interactive login shells2.However, when you send a command over ssh the way you're doing with paramiko, that command is by default invoked in a noninteractive (non-login) shell. In this case, your configuration files are not sourced3, which is why the commands you expect to be available are not.
How to fix it:
The easiest way would be to simply change
cli.exec_command(<command>)
tocli.exec_command('/bin/bash -lc "<command>"')
. The-l
flag causesbash
to behave as though it were invoked in a login shell, meaning it will source all the same configuration files it does when you ssh in from your terminal.If you need an interactive shell, you could instead use
cli.get_pty()
andcli.invoke_shell()
, but this isn't necessary for just running a Python script.Finally, I highly recommend taking a look at
spurplus
. It's built on top ofspur
, which is in turn built on top ofparamiko
, and it adds some nice extra features in addition to being much easier to use.1this is true for Linux systems. On MacOS, subsequent interactive shells you launch are also login shells.
2there are also interactive non-login shells, which instead source your
.bashrc
. Again, some of this is slightly different for non-Linux machines, as well as other shells like Zsh.3unless you've specified a
$BASH_ENV
file.