4

sshを使用してリモートbashスクリプトを呼び出すために、shlexでsubprocess.popenを使用しています。このコマンドは、bash 自体で非常にうまく機能します。しかし、subprocess.popen を使用して python と shlex に変換しようとするとすぐに、エラーが発生します。

リモート bash スクリプト:

#!/bin/bash
tmp="";     
while read -r line;
do
    tmp="$tmp $line\n";
done;
echo $tmp;

BASH CMD RESULT (コマンドラインでのリモート bash スクリプトの呼び出し)

$> ssh x.x.x.x cat < /tmp/bef69a1d-e580-5780-8963-6a9b950e529f.txt " | /path/to/bash/script.sh;"
Bar\n
$> 

Python コード

import shlex
import subprocess

fn = '/tmp/bef69a1d-e580-5780-8963-6a9b950e529f.txt'
s = """                                                                    
ssh x.x.x.x cat < {localfile} '| /path/to/bash/script.sh;'
""".format(localfile=fn)

print s

lexer = shlex.shlex(s)                                                     
lexer.quotes = "'"                                                         
lexer.whitespace_split = True                                              
sbash = list(lexer)                                                        
print sbash                                                                

# print buildCmd                                                           
proc=subprocess.Popen(sbash,stdout=subprocess.PIPE,stderr=subprocess.PIPE) 
out,err=proc.communicate()                                                 

print "Out: " + out                                                        
print "Err: " + err                                                        

PYTHON スクリプトの結果:

$> python rt.py

    ssh x.x.x.x cat < /tmp/bef69a1d-e580-5780-8963-6a9b950e529f.txt '| /path/to/bash/script.sh'
['ssh', 'x.x.x.x', 'cat', '<', '/tmp/bef69a1d-e580-5780-8963-6a9b950e529f.txt', "'| /path/to/bash/script.sh'"]
Out: 
Err: bash: /tmp/bef69a1d-e580-5780-8963-6a9b950e529f.txt: No such file or directory
$>

私は何が欠けていますか?

4

2 に答える 2

4

問題は、コマンドでシェル リダイレクトを使用しているが、サブプロセスを使用するときにシェルが生成されないことです。

次の (非常に単純な) プログラムを考えてみましょう。

import sys
print sys.argv

実行しているように実行するとssh(存在すると仮定foofile.txt)、次のようになります。

python argcheck.py ssh cat < foofile.txt " | /path/to/bash/script.sh;"
['argcheck.py', 'ssh', 'cat', ' | /path/to/bash/script.sh;']

< foofile.txtpython のコマンドライン引数には決して到達しないことに注意してください。これは、bash パーサーが<と その後に続くファイルをインターセプトし、そのファイルの内容をプログラムの stdin にリダイレクトするためです。つまり、ssh標準入力からファイルを読み取っています。python を使用stdinしてファイルを渡すことも必要です。ssh

s = """                                                                    
ssh x.x.x.x cat '| /path/to/bash/script.sh;'
"""

#<snip>

proc=subprocess.Popen(sbash,stdout=subprocess.PIPE,stderr=subprocess.PIPE,
                            stdin=subprocess.PIPE)
out,err=proc.communicate(open(fn).read())

おそらく動作します。


以下は私にとってはうまくいきます:

import subprocess
from subprocess import PIPE

with open('foo.h') as f:
    p = subprocess.Popen(['ssh','mgilson@XXXXX','cat','| cat'],stdin=f,stdout=PIPE,stderr=PIPE)
    out,err = p.communicate()
    print out
    print '#'*80
    print err

そして同等のコマンドは次のbashとおりです。

ssh mgilson@XXXXX cat < foo.h '| cat'

foo.hローカル マシン上のファイルはどこですか。

于 2012-11-07T19:51:40.593 に答える
0

仲買人をやめてParamikoを使ってみませんか?

于 2012-11-07T20:50:57.107 に答える