如何从python中的shell获取变量? [英] How to get a variable from the shell in python?

查看:73
本文介绍了如何从python中的shell获取变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个脚本,该脚本需要通过运行它的 Linux 机器的本地 dbus 来利用 Java 守护进程.特别是这个守护进程将返回一个我想要的元组数组,以便我可以在我的代码后面解析/使用这些信息.我希望这段代码一次从多台机器上获取这个值,但问题是我看到真正从终端获取返回/退出值的唯一方法是解析 stdout 的输出.我不想这样做,我更喜欢获得实际变量.现在我有这个:

导入操作系统message = "import dbus, sys\nbus=dbus.SystemBus()\nremote_object=bus.get_object('daemon.location', '/daemon')\ncontroller=dbus.Interface(remote_object, 'daemon.path')\nsys.exit(controller.getValue())"x = os.system('echo \-e "%s" \| ssh %s python' %(message, ip))

在这个例子中,当我运行controller.getValue()"时,它返回一个元组数组.我试图找出一种方法来获取该数组.当使用类似 popen 之类的东西时,它将 stdout 中的输出通过管道传输到一个文件中并将其返回给您,这样您就可以得到一个与数组等效的字符串.我想弄清楚的是如何获得实际的数组.好像将退出 ssh tty 时返回的变量传递到我的代码中.有什么想法吗?

解决方案

如果没有共享内存,就无法避免序列化.线路上只有字节.您可以使用一个库来隐藏它,例如,使用 execnet 模块:

#!/usr/bin/env python导入执行网gw = execnet.makegateway("ssh=user@host")channel = gw.remote_exec("""导入 dbus, sys总线 = dbus.SystemBus()remote_object = bus.get_object('daemon.location', '/daemon')控制器 = dbus.Interface(remote_object, 'daemon.path')channel.send(controller.getValue())""")元组_ = channel.receive()打印元组_打印元组_[0]

但是使用 ast.literal_eval 自己解析简单的元组值很容易() 来自标准库:

#fabfile.py进口AST从 fabric.api 导入运行def getcontroller():"""返回控制器值."""cmd = """导入 dbus, sys总线 = dbus.SystemBus()remote_object = bus.get_object('daemon.location', '/daemon')控制器 = dbus.Interface(remote_object, 'daemon.path')打印 repr(controller.getValue())""" #注意:您必须转义所有引号output = run('python -c "%s"' % cmd)tuple_ = ast.literal_eval(输出)打印元组_[0]

示例:$ fab getcontroller -H user@host

这里我使用了 fabric 在远程主机上运行命令.

如果另一端不生成 Python 文字,您可以使用 JSON 作为序列化格式:

<预><代码>>>>导入json>>>t = (1, "a")>>>json.dumps(t)'[1, "a"]'>>>json.loads(_)[1, u'a']>>>

I'm writing a script that needs to take advantage of a Java daemon via the local dbus of the linux machines it will run on. This daemon in particular will return an array of tuples which I want so that I can parse through/use the information in later in my code. I want this code to take this value from multiple machines at once, but the problem is the only way I see to really take return/exit values from a terminal which I am ssh'ed into is by parsing stdout's output. I don't want to do this, I'd much prefer to get the actual variable. Right now I have this:

import os
message = "import dbus, sys\nbus=dbus.SystemBus()\nremote_object=bus.get_object('daemon.location', '/daemon')\ncontroller=dbus.Interface(remote_object, 'daemon.path')\nsys.exit(controller.getValue())"
x = os.system('echo \-e "%s" \| ssh %s python' %(message, ip))

In this example when I run "controller.getValue()" it returns an array of tuples. I'm trying to figure out a way to get that array. When using something like popen it pipes the output in stdout into a file and returns it to you, that way you get a string equivalent of the array. What I'm trying to figure out is how to get the actual array. As if to pass the variable returned when exiting the ssh tty into my code. Any ideas?

解决方案

You can't avoid serialization if there is no shared memory. There are only bytes on the wire. You could use a library that hides it from you e.g., with execnet module:

#!/usr/bin/env python
import execnet

gw = execnet.makegateway("ssh=user@host")
channel = gw.remote_exec("""
import dbus, sys

bus = dbus.SystemBus()
remote_object = bus.get_object('daemon.location', '/daemon')
controller = dbus.Interface(remote_object, 'daemon.path')

channel.send(controller.getValue())
""")
tuple_ = channel.receive()
print tuple_
print tuple_[0]

But it easy to parse simple tuple values yourself using ast.literal_eval() from stdlib:

#fabfile.py
import ast
from fabric.api import run

def getcontroller():
    """Return controller value."""
    cmd = """
import dbus, sys

bus = dbus.SystemBus()
remote_object = bus.get_object('daemon.location', '/daemon')
controller = dbus.Interface(remote_object, 'daemon.path')

print repr(controller.getValue())
""" #NOTE: you must escape all quotation marks
    output = run('python -c "%s"' % cmd)
    tuple_ = ast.literal_eval(output)
    print tuple_[0]

Example: $ fab getcontroller -H user@host

Here I've used fabric to run the command on remote host.

You could use JSON as a serialization format if the other end doesn't produce Python literals:

>>> import json
>>> t = (1, "a")
>>> json.dumps(t)
'[1, "a"]'
>>> json.loads(_)
[1, u'a']
>>>

这篇关于如何从python中的shell获取变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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