【问题标题】:Sftp in python by invoking unix-shell commands通过调用 unix-shell 命令在 python 中进行 Sftp
【发布时间】:2012-05-11 02:57:00
【问题描述】:

我们如何通过在 python 脚本中使用 os.system 调用 unix shell 命令,将文件从源主机 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

【问题讨论】:

  • 为什么要使用os.system 向文件写入行?为什么不只是openprint

标签: python unix command sftp


【解决方案1】:

您应该将您的命令通过管道传输到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>)

最后是)

字符串表达式由一个应用了%格式的字符串文字组成:

"string literal" % locals()

字符串文字包含对 shell 的重定向:

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

一起:

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

。但如前所述,这是我能想象到的最糟糕的解决方案 - 更好地直接写入临时文件,甚至更好地直接进入子进程。

【讨论】:

    【解决方案2】:

    嗯,我认为你的问题的字面解决方案看起来像这样:

    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 之类的东西来帮助进行持续的自动化。

    【讨论】:

      【解决方案3】:

      如果您希望在任何 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))
      

      快速免责声明:我没有在 shell 中运行它,因此可能存在拼写错误。如果是这样,请给我评论,我会更正。

      【讨论】:

        猜你喜欢
        • 2013-03-18
        • 1970-01-01
        • 1970-01-01
        • 2011-08-20
        • 2013-11-22
        • 1970-01-01
        • 2015-07-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多