gpt4 book ai didi

linux - 使用 paramiko ssh channel 以 root 权限运行远程程序

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:04:00 30 4
gpt4 key购买 nike

我想用root权限远程执行一个程序tcp_sender,下面的函数用于建立ssh连接

    def connect(hostname):
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname, username='usr', pkey=paramiko.RSAKey.from_private_key(open('id_rsa'), 'psw'), timeout = 240.0)
return ssh

那么我有3个解决方案:

解决方案A)

    ssh = connect(hostname)
chan = ssh.invoke_shell()
chan.send('sudo ./tcp_sender\n')

用这个方案,远程的tcp_sender没有执行,我用ps -ef|grep "tcp_sender"查了一下,没有进程

我试过 chan.send('sudo ./tcp_sender > log 2>&1\n')在日志中,它说:

sudo: no tty present and no askpass program specified

解决方案B)

    ssh = connect(hostname)
(stdin, stdout, stderr) = ssh.exec_command("[ -f tcp_sender ] && echo 1 || echo 0")
res = stdout.readlines()
print hostname,res[0]
if res[0] == '0\n':
UnusedHostFile.write(hostname+'no tcp_sender exists\n')
else:
chan = ssh.invoke_shell()
chan.send("sudo chmod 777 tcp_sender\n")
# if a tcp_sender is runnning, kill it
chan.send('x=`ps -ef|grep "tcp_sender"|grep -v "grep"|awk \'{print $2}\'`; [ -n "${x}" ] && sudo kill -9 $x\n')
time.sleep(4)
while not chan.recv_ready():
time.sleep(1)
buf = ''
buf +=chan.recv(9999)
print buf
chan.send('sudo ./tcp_sender\n')

使用此解决方案,我只需添加一些不相关的行,然后远程 tcp_sender 就会运行,例如:

bash-4.0# ps -ef|grep "sender"
root 9348 9325 0 Apr07 ? 00:00:00 sudo ./tcp_sender
root 9349 9348 0 Apr07 ? 00:00:00 ./tcp_sender

但是,它无法正常运行(如预期的那样)。在tcp_sender中,有一个fork(),可能是这个原因吧?

我试过 chan.send('sudo ./tcp_sender > log 2>&1\n')在日志中,它是空的。因为我的tcp_sender程序中有很多错误检查相关的printf,我想日志里应该有printf结果,但是是空的.

另外,我注意到一个现象,如果我kill -9 9348,这两个进程都结束了。但是对于下一个解C,进程9349会交给系统init进程1。

解决方案C):

使用此解决方案,我可以正确运行远程 tcp_sender。但是python脚本会被远程程序阻塞,直到退出。我不希望我的脚本等待远程退出。

    log = open('log','a+')
ssh = connect(hostname)
(stdin, stdout, stderr) = ssh.exec_command("[ -f tcp_sender ] && echo 1 || echo 0")
res = stdout.readlines()
print hostname,res[0]
if res[0] == '0\n':
UnusedHostFile.write(hostname+"tcp_sender doesn't exists\n")
else:
chan = ssh.invoke_shell()
chan.send("sudo chmod 777 tcp_sender\n")
chan.send('x=`ps -ef|grep "tcp_sender"|grep -v "grep"|awk \'{print $2}\'`; [ -n "${x}" ] && sudo kill -9 $x\n')
time.sleep(4)
while not chan.recv_ready():
time.sleep(1)
buf = ''
buf +=chan.recv(9999)
print buf
chan.send('sudo ./tcp_sender\n')
#chan.send('sudo whoami\n')
time.sleep(2)
(stdin, stdout, stderr) = ssh.exec_command("ps -ef|grep 'tcp_sender'|grep -v 'grep'|wc -l")
res = stdout.readlines()
while res[0].strip() != '0':
time.sleep(3)
(stdin, stdout, stderr) = ssh.exec_command("ps -ef|grep 'tcp_sender'|grep -v 'grep'|wc -l")
res = stdout.readlines()
print res[0].strip()
while not chan.recv_ready():
time.slepp(1)
buf = ''
buf += chan.recv(9999)
log.write(hostname+': '+''.join(str(elem) for elem in buf)+'\n\n')
log.close()

那么造成这种现象的潜在原因是什么?任何人都可以提供一些建议吗?谢谢!

最佳答案

您正在混合您可能应该分开的东西。

首先,在远程端编写一个脚本,usr(=您给定的用户名paramiko)可以执行并且可以使用正确启动tcp_sender sudo 无需输入密码等

在脚本中,使用nohup启动sudo作为后台进程:

nohup sudo ./tcp_sender

nohup 确保新的子进程被正确分离,以便在连接丢失/切断时它保持事件状态。

当此脚本运行时,使用 ssh.exec_command('script') 启动新脚本

推理:使用 shell 和驱动 shell 的智能 Python 代码,就好像您正在键入命令一样,它可能会做您想做的事情。但它总是很脆弱,难以测试 - 它是 God object 的变体.

相反,将您的问题拆分为您可以独立开发和测试的不同的小问题。您需要解决三个问题:

  1. tcp_sender 本身。
  2. 启动tcp_sender
  3. 远程启动

所以使用三种不同的工具来解决它们。

关于linux - 使用 paramiko ssh channel 以 root 权限运行远程程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16085502/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com