2012-05-11 5 views
2

がどのように我々は...助けてくださいos.systemを使用してPythonスクリプトでは、UNIXのシェルコマンドを呼び出すことによって、Pythonでdestinitionサーバに送信元ホストからファイルをSFTPできるコマンドSFTPは

I have tried the following code 

dstfilename="hi.txt" 
host="abc.com" 
user="sa" 

os.system("echo cd /tmp >sample.txt) 
os.system("echo put %(dstfilename)s" %locals()) // line 2 
os.system("echo bye >>sample.txt") 
os.system("sftp -B /var/tmp/sample.txt %(user)[email protected]%(host)s) 


How to append this result of line to sample.txt? 
os.system("echo put %(dstfilename)s %locals()) >>sample.txt" // Seems this is syntatically not correct. 

cat>sample.txt  //should look like this 
cd /tmp 
put /var/tmp/hi.txt 
bye 

Any help? 

Thanks you 
+1

なぜ 'os.system'を使ってファイルに行を書いていますか?なぜ、 'open'と' print'だけではないのですか? – larsks

答えて

0

まあ、私はあなたの質問へのリテラルのソリューションは、このようなものに見えると思います:@larsksが言うようにあなたのためのtmpファイルを作成するために適切なのFileHandlerを使用し、

import os 
dstfilename="/var/tmp/hi.txt" 
samplefilename="/var/tmp/sample.txt" 
host="abc.com" 
user="sa" 

with open(samplefilename, "w") as fd: 
    fd.write("cd /tmp\n") 
    fd.write("put %s\n" % dstfilename) 
    fd.write("bye\n") 

os.system("sftp -B %s %[email protected]%s" % (samplefilename, user, host)) 

を、そして私の個人的な好みは何をするではないことですlocals()を使用した文字列フォーマット。

しかし、ユースケースによっては、これは特に適切なアプローチではないと思います。たとえば、sftpサイトのパスワードはどのように入力されますか?

私はあなたがParamikoSFTPClientで見ていた、またはあなたが現在進行中の自動化を支援するpexpectのようなものを必要とするかもしれない、ということができない場合は、より堅牢なソリューションを取得したいと思います。

2

コマンドをsftpにパイプする必要があります。あなたの質問に答えるために、

import os 
import subprocess 

dstfilename="/var/tmp/hi.txt" 
samplefilename="/var/tmp/sample.txt" 
target="[email protected]" 

sp = subprocess.Popen(['sftp', target], shell=False, stdin=subprocess.PIPE) 

sp.stdin.write("cd /tmp\n") 
sp.stdin.write("put %s\n" % dstfilename) 
sp.stdin.write("bye\n") 

[ do other stuff ] 

sp.stdin.write("put %s\n" % otherfilename) 

[ and finally ] 

sp.stdin.write("bye\n") 
sp.stdin.close() 

:しかし、このような何かを試してみてください。もちろん、

os.system("echo put %(dstfilename)s %locals()) >>sample.txt" // Seems this is syntatically not correct. 

ことはありません。文字列をos.systemに渡したいとします。だから、最後に)

os.system(<string expression>) 

に見えるように持っています。

文字列式を適用%書式とリテラル文字列からなる:

"echo put %(dstfilename)s >>sample.txt" 

一緒:

os.system("echo put %(dstfilename)s >>sample.txt" % locals()) 

"string literal" % locals() 

リテラル文字列は、シェルのリダイレクトを含ま

。しかし、これは私が想像できる最悪の解決策です。一時ファイルに直接書き込む方がいいし、パイプをサブプロセスに直接書き込む方がよいでしょう。

0

sftpコマンドのいずれかが失敗した場合にゼロ以外の戻りコードが必要な場合は、コマンドをファイルに書き込んでから、sftpバッチを実行する必要があります。このようにして、戻りコードを検索して、sftpコマンドに障害が発生していないかどうかを確認できます。

は、ここでは簡単な例です:

import subprocess 

host="abc.com" 
user="sa" 

user_host="%[email protected]%s" % (user, host) 

execute_sftp_commands(['put hi.txt', 'put myfile.txt']) 

def execute_sftp_commands(command_list): 
    with open('batch.txt', 'w') as sftp_file: 
     for sftp_command in sftp_command_list: 
      sftp_file.write("%s\n" % sftp_command) 
     sftp_file.write('quit\n') 
    sftp_process = subprocess.Popen(['sftp', '-b', 'batch.txt', user_host], shell=False) 
    sftp_process.communicate() 
    if sftp_process.returncode != 0: 
     print("sftp failed on one or more commands: {0}".format(sftp_command_list)) 

クイック免責事項:私はタイプミスが存在する可能性のあるシェルでこれを実行しませんでした。もしそうなら、私にコメントを送ってください。私は正しいでしょう。