使用"su -l"执行命令.在SSH中使用Python [英] Executing command using "su -l" in SSH using Python

查看:163
本文介绍了使用"su -l"执行命令.在SSH中使用Python的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的朋友服务器仅允许一个用户从SSH登录,因此通常我只是以该用户身份登录,然后执行su -l myuser来更改帐户.我想使用Python自动执行一些无聊的工作,但是我遇到了问题.显然,我首先尝试过的Paramiko模块为每个命令调用了一个shell,所以这是不可能的.后来我尝试使用invoke_shell()克服了这个问题,但仍然失败了(我认为这是因为更改用户也会更改shell).

此后,我发现了有关Fabric模块的信息,但最好的办法是打开SSH shell,并以适当的用户身份登录,但没有选择运行代码中的任何命令的方法.

有什么办法可以做到这一点?最终目标可能看起来像这样:

ssh.login(temp_user, pass)
ssh.command("su -l myuser")
expect("Password: ", ssh.send("mypass\n")
ssh.command("somescript.sh > datadump.txt")

使用sudo以及添加无密码登录都是不可能的.

这里建议的是我使用Paramiko尝试的代码:

import paramiko

host = "hostip"
user = "user"
user_to_log = "myuser"
password = "pass"
password_to_log = "mypass"

login_command = "su -l " + user_to_log

ssh = paramiko.SSHClient()
ssh.load_system_host_keys()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostip, username=user, 
    password=password)    

transport = ssh.get_transport()
session = transport.open_session()
session.set_combine_stderr(True)
session.get_pty()


session.exec_command("su -l " + user_to_log)
stdin = session.makefile('wb', -1)


stdin.write(password_to_log +'\n')
stdin.flush()

session.exec_command("whoami")
stdout = session.makefile('rb', -1)

for line in stdout.read().splitlines():        
    print('host: %s: %s' % (host, line))


su -c command也不起作用,因为服务器系统不支持该选项.

解决方案

一般免责声明(针对那些偶然发现此问题的人):


如果上述方法均不可行(并且您确实尽力使管理员启用上述某些选项):

作为最后的选择,您可以将命令写到su的标准输入中,就像您已经写过密码一样(另一件事是不做):

stdin, stdout, stderr = session.exec_command("su -l " + user_to_log)

stdin.write(password_to_log + '\n')
stdin.flush()

command = 'whoami'
stdin.write(command + '\n')
stdin.flush()

(还要注意,调用makefile是多余的,因为exec_command已经返回了该值)

请参见在Python Paramiko中的SSH服务器上的辅助Shell/命令中执行(子)命令.


请注意,您的问题不是关于要使用哪个SSH客户端库.不管您使用Paramiko还是其他.这实际上是一个通用的SSH/shell问题.

I use a friends server that allows only one user to be logged from SSH, so normally I just log in as that user and then do su -l myuser to change accounts. I wanted to automate some boring stuff using Python, but I ran into problems with that. Apparently Paramiko module that I tried first invokes a single shell for every command, so that was out of the question. Later I tried using invoke_shell() to overcome that, but it still failed (I assume it's because changing user changes shell as well).

After that I found about Fabric module, but best I could do is open SSH shell with a proper user logged in, but without option to run any commands from code.

Is there any way to accomplish that? Final goal would probably look something like this:

ssh.login(temp_user, pass)
ssh.command("su -l myuser")
expect("Password: ", ssh.send("mypass\n")
ssh.command("somescript.sh > datadump.txt")

Using sudo is impossible, as well as adding passwordless login.

As suggested here is the code that I tried with Paramiko:

import paramiko

host = "hostip"
user = "user"
user_to_log = "myuser"
password = "pass"
password_to_log = "mypass"

login_command = "su -l " + user_to_log

ssh = paramiko.SSHClient()
ssh.load_system_host_keys()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostip, username=user, 
    password=password)    

transport = ssh.get_transport()
session = transport.open_session()
session.set_combine_stderr(True)
session.get_pty()


session.exec_command("su -l " + user_to_log)
stdin = session.makefile('wb', -1)


stdin.write(password_to_log +'\n')
stdin.flush()

session.exec_command("whoami")
stdout = session.makefile('rb', -1)

for line in stdout.read().splitlines():        
    print('host: %s: %s' % (host, line))


su -c command won't work either, since server system doesn't support that option.

解决方案

General disclaimers first (to others who stumble upon this question):


If none of the above is feasible (and you really tried hard to make the admin enable some of the options above):

As the last resort option, you can write the command to a standard input of the su, the same way you already write a password (another thing not to do):

stdin, stdout, stderr = session.exec_command("su -l " + user_to_log)

stdin.write(password_to_log + '\n')
stdin.flush()

command = 'whoami'
stdin.write(command + '\n')
stdin.flush()

(also note that it's redundant to call makefile, as exec_command already returns that)

See Execute (sub)commands in secondary shell/command on SSH server in Python Paramiko.


Note that your question is not about which SSH client library to use. It does not matter if you use Paramiko or other. This all is actually a general SSH/shell question.

这篇关于使用"su -l"执行命令.在SSH中使用Python的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆