2011-10-11 8 views
1

Java가 실행될 Linux 머신의 로컬 dbus를 통해 Java 데몬을 활용해야하는 스크립트를 작성하고 있습니다. 이 데몬은 특히 튜토리얼의 배열을 반환 할 것이므로 나중에 코드를 통해 구문 분석하고 사용할 수 있습니다. 이 코드가 여러 컴퓨터에서이 값을 한꺼번에 가져 오길 원하지만 문제는 stdout의 출력을 구문 분석하여 ssh로 처리되는 터미널에서 반환 값/종료 값을 실제로 가져 오는 유일한 방법입니다. 나는 이것을하고 싶지 않다. 나는 실제 변수를 얻는 것을 선호한다. 지금 당장이 있습니다 :파이썬에서 쉘에서 변수를 가져 오는 방법은 무엇입니까?

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)) 

이 예제에서 나는 "controller.getValue()"를 실행할 때 튜플의 배열을 반환합니다. 그 배열을 얻을 수있는 방법을 찾으려고 노력 중입니다. popen과 같은 것을 사용하면 stdout의 출력을 파일로 파이프하고 그것을 여러분에게 반환합니다. 그러면 여러분은 배열과 같은 문자열을 얻을 수 있습니다. 알아 내려고하는 것은 실제 배열을 얻는 방법입니다. 마치 ssh tty를 종료 할 때 반환 된 변수를 내 코드로 전달하는 것과 같습니다. 어떤 아이디어?

+0

: 출력을 구문 분석 변수로 배치. 그것을 피할 방법이 없습니다. –

답변

1

를 얻을 수 있습니다. 유선에는 바이트 만 있습니다. 당신은 execnet 모듈, 당신이 예에서 숨 깁니다 라이브러리를 사용할 수 있습니다

#!/usr/bin/env python 
import execnet 

gw = execnet.makegateway("[email protected]") 
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] 

그러나 그것은 쉬운 간단한 튜플 자신이 다음 stdlib에서 ast.literal_eval()를 사용하여 값 구문 분석 :

#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] 

예 : $ fab getcontroller -H [email protected]

여기서는 fabric을 사용하여 원격 호스트에서 명령을 실행했습니다. 다른 쪽 끝은 파이썬 리터럴을 생성하지 않는 경우

당신은 직렬화 형식으로 JSON을 사용할 수

쉘이 일을 정확히 무엇
>>> import json 
>>> t = (1, "a") 
>>> json.dumps(t) 
'[1, "a"]' 
>>> json.loads(_) 
[1, u'a'] 
>>> 
+0

아, 정말 고마워! 이것은 내가 찾고 있었던 바로 그 것이다. – SuperFamousGuy

0

왜 popen을 사용하지 않습니까?

lines = os.popen("your command here").readlines() 
+0

이것은 내가 피하려고했던 말을합니다. 그것은 당신의 tty에서 stdout의 출력을 파싱합니다. os.popen은 stdout의 값을 반환하는 파일 객체로 파이프합니다. 실제로 내 데몬이 반환하는 변수를 얻으려고합니다. – SuperFamousGuy

+0

몇 가지 프로세스와 기계가 관련되어 있기 때문에 약간 까다로울 수 있습니다. 각 프로세스는 상태를 부모에게 반환하므로 부모 프로세스는 상태를 다시 전달해야합니다. 왜 popen의 출력을 파싱하는 것이 좋지 않은가요? – Richie

+0

잠재적 인 O (1) 최악의 시나리오 O (log (n))에서 O (n) 로의 효율성을 떨어 뜨리게됩니다. 그것은 세계에서 최악의 상황이 아닙니다. 더 좋은 방법이 있는지 궁금 해서요. 그것은 가능해야하는 것들 중 하나처럼 보이지만 어떻게 해야할지 잘 모르겠습니다. – SuperFamousGuy

0

그냥 쉘 변수를 원하는 경우에 당신이 할 수있는이

$ FOO="myFOO" 
$ export FOO 
$ cat x.py 
#!/usr/bin/python 
import os 
print os.environ['FOO'] 
$ ./x.py 
myFOO 
$ 

당신이 프로그램의 리턴 코드를 원하는 경우 :

당신은 아마 조금 더 나은 요구 사항을 설명 할 수있는 경우에는 공유 메모리가없는 경우
try: 
    retcode = call("mycmd" + " myarg", shell=True) 
    if retcode < 0: 
     print >>sys.stderr, "Child was terminated by signal", -retcode 
    else: 
     print >>sys.stderr, "Child returned", retcode 
except OSError, e: 
    print >>sys.stderr, "Execution failed:", e 

, 당신은 더 나은 도움을 당신은 직렬화를 피할 수

+0

죄송합니다. 약간 막연한 경우 좀 더 명확하게하려고 게시물을 편집했습니다. 그것은 귀하의 코드가 쉘에서 실행되거나 쉘 출력을 변수로 파싱하는 것 같습니다. 나는 쉘에서 변수 (이 경우에는 배열)를 취하려고한다는 점에서 반대의 일을하려고한다. – SuperFamousGuy

관련 문제