使用"su -l"执行命令.在SSH中使用Python [英] Executing command using "su -l" in SSH using 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
不是正确的解决方案.su
是旨在用于交互式用途而非自动化的工具.正确的解决方案是直接使用正确的帐户登录.或者至少使用无密码的
sudo
.或者您可以使用
setuid
右键创建根所有者脚本.. > -
如果坚持使用
su
,在大多数系统上,可以使用-c
切换到su
来指定命令:su -c "whoami" user
如果上述方法均不可行(并且您确实尽力使管理员启用上述某些选项):
作为最后的选择,您可以将命令写到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):
Using
su
is not the right solution.su
is a tool intended for an interactive use, not for an automation. The correct solution is to login with the correct account directly.Or at at least use a password-less
sudo
.Or you can create a root-owner script with
setuid
right.See also Allowing automatic command execution as root on Linux using SSH.
If you are stuck with
su
, on most systems you can use-c
switch tosu
to specify a command:su -c "whoami" user
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屋!