4

os.systemを使用してPythonスクリプトでunixシェルコマンドを呼び出すことにより、Pythonでソースホストから宛先サーバーにファイルを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)s@%(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
4

3 に答える 3

7

コマンドを にパイプする必要がありますsftp。次のようなことを試してください:

import os
import subprocess

dstfilename="/var/tmp/hi.txt"
samplefilename="/var/tmp/sample.txt"
target="sa@abc.com"

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

)末尾に aを付けます。

文字列式は、%フォーマットが適用された文字列リテラルで構成されます。

"string literal" % locals()

文字列リテラルには、シェルのリダイレクトが含まれています。

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

そして一緒に:

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

. しかし、前述のように、これは私が想像できる最悪の解決策です。一時ファイルに直接書き込むか、サブプロセスに直接パイプすることをお勧めします。

于 2012-05-11T05:47:06.743 に答える
0

sftp コマンドのいずれかが失敗した場合にゼロ以外のリターン コードが必要な場合は、コマンドをファイルに書き込んでから、それらに対して sftp バッチを実行する必要があります。この方法で、リターン コードを取得して、sftp コマンドが失敗したかどうかを確認できます。

簡単な例を次に示します。

import subprocess

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

user_host="%s@%s" % (user, host)

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

def execute_sftp_commands(sftp_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))

簡単な免責事項: これはシェルで実行していないため、タイプミスがある可能性があります。もしそうなら、私にコメントを送ってください、そして私は修正します。

于 2016-08-17T06:26:57.780 に答える
0

さて、あなたの質問に対する文字通りの解決策は次のようになると思います:

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 %s@%s" % (samplefilename, user, host))

@larsks が言うように、適切なファイル ハンドラを使用して tmp ファイルを作成します。私の個人的な好みは、locals().

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

ParamikoのSFTPClientを見てみると、より堅牢なソリューションが得られると思います。失敗した場合は、進行中の自動化を支援するためにpexpectのようなものが必要になる場合があります。

于 2012-05-11T03:59:03.667 に答える