【问题标题】:Using a Python subprocess call to invoke a Python script使用 Python 子进程调用来调用 Python 脚本
【发布时间】:2011-11-01 09:55:42
【问题描述】:

我有一个 Python 脚本需要调用同一目录中的另一个 Python 脚本。我这样做了:

from subprocess import call
call('somescript.py')

我收到以下错误:

call('somescript.py')
File "/usr/lib/python2.6/subprocess.py", line 480, in call
return Popen(*popenargs, **kwargs).wait()
File "/usr/lib/python2.6/subprocess.py", line 633, in __init__
errread, errwrite)
File "/usr/lib/python2.6/subprocess.py", line 1139, in _execute_child

raise child_exception
OSError: [Errno 2] No such file or directory

我在同一个文件夹中有脚本 somescript.py。我在这里遗漏了什么吗?

【问题讨论】:

  • . 在您的PATH 中吗? somescript.py 是可执行文件吗?
  • 你为什么要执行它?为什么不import呢?
  • @wooble 是的。它也在路径中并且也是可执行的。是的。我也可以导入它。但是无论如何都想知道我在这里做错了什么,因为我认为这应该有效。
  • 为什么不导入?!原因很多:真正执行,即使已经导入;有__name__ == '__main__;运行多次。
  • 另外:如果它不是 Python 2,并且在同一目录中的其他脚本 - 它不会只是简单地导入。您可能需要将其目录添加到 sys.path,但出于多种原因您可能不想这样做:它们之间的安全性(名称冲突...)。

标签: python subprocess


【解决方案1】:

如果“somescript.py”不是您通常可以直接从命令行执行的东西(即$: somescript.py 有效),那么您不能直接使用 call 调用它。

请记住,Popen 的工作方式是第一个参数是它执行的程序,其余的是传递给该程序的参数。在这种情况下,程序实际上是 python,而不是您的脚本。因此,以下内容将按您的预期工作:

subprocess.call(['python', 'somescript.py', somescript_arg1, somescript_val1,...]).

这会正确调用 Python 解释器并告诉它使用给定的参数执行您的脚本。

请注意,这与上述建议不同:

subprocess.call(['python somescript.py'])

这将尝试执行名为 python somscript.py 的程序,该程序显然不存在。

call('python somescript.py', shell=True)

也可以,但使用字符串作为调用的输入不是跨平台的,如果您不是构建字符串的人,则很危险,通常应尽可能避免。

【讨论】:

  • 我有这个问题,但是脚本的路径在我的 basrc 文件中,所以我可以从终端调用它作为 myscript (args)。当我尝试从 python 执行上述操作时,出现未找到错误?
  • 根据 Python 3.5 中的documentation,您现在可以使用run() 而不是call()
  • 这有点简单 - 为什么只是 python - 它在你的路上吗?它会是您正在运行的同一个解释器吗?
  • 我建议把'python'改成sys.executable(stackoverflow.com/questions/2589711/…,stackoverflow.com/questions/5927633/…),就可以了。
【解决方案2】:

窗户? Unix?

Unix 需要一个 shebang 和 exec 属性才能工作:

#!/usr/bin/env python

作为脚本的第一行并且:

chmod u+x script.py

在命令行或

call('python script.py'.split())

如前所述。

如果您将shell=True parameter 添加到“调用”调用中,Windows 应该可以工作。

【讨论】:

  • call('python script.py') 无法在非 Windows 系统上运行。应该是check_call([sys.executable or 'python', '/path/to/script.py'])。如果指定了python 可执行文件,则不需要shebang 和可执行权限。
  • sys.executable 应该足以应付所有正常情况。
【解决方案3】:

看看这个。

from subprocess import call 
with open('directory_of_logfile/logfile.txt', 'w') as f:
   call(['python', 'directory_of_called_python_file/called_python_file.py'], stdout=f)

【讨论】:

    【解决方案4】:

    subprocess.call 需要与 subprocess.Popen 相同的参数 - 这是一个字符串列表(C 中的 argv)而不是单个字符串。

    您的子进程很有可能尝试使用参数“o”、“m”、“e”、...运行“s”

    【讨论】:

      【解决方案5】:

      如果您使用的是 Linux/Unix,则可以完全避免 call() 并且不执行 Python 可执行文件及其环境的全新实例。

      import os
      
      cpid = os.fork()
      if not cpid:
          import somescript
          os._exit(0)
      
      os.waitpid(cpid, 0)
      

      物有所值。

      【讨论】:

      • 仅 *nix:使用 fork 您将从父进程 python 解释器继承(包含所有现有的导入,...)。如果您想要一个全新的口译员,这不是一个好的选择。请参阅 diff fork/exec unix 系统调用。
      • subprocess 模块在 POSIX 系统上使用 fork/exec,在 Windows 上使用 CreateProcess。如果要运行 Python 脚本,无需直接使用fork
      【解决方案6】:
      import subprocess
      command = 'home/project/python_files/run_file.py {} {} {}'.format(
              arg1, arg2, arg3) # if you want to pass any arguments
      p = subprocess.Popen(
              [command],
              shell=True,
              stdin=None,
              stdout=subprocess.PIPE,
              stderr=subprocess.PIPE,
              close_fds=True)
      out, err = p.communicate()
      

      【讨论】:

        【解决方案7】:

        首先,检查somescript.py 是否可执行并以#!/usr/bin/python 的行开头。 如果这样做了,那么您可以使用subprocess.call('./somescript.py')

        或者正如另一个答案指出的那样,您可以使用subprocess.call(['python', 'somescript.py'])

        【讨论】:

        • 只是一个随机指针:我发现使用 #!/usr/bin/env python 很有用,这样如果模块已加载,您将自动使用加载的 python 版本运行.
        【解决方案8】:
        def main(argv):
            host = argv[0]
            type = argv[1]
            val = argv[2]
        
            ping = subprocess.Popen(['python ftp.py %s %s %s'%(host,type,val)],stdout = subprocess.PIPE,stderr = subprocess.PIPE,shell=True)
            out = ping.communicate()[0]
            output = str(out)
            print output
        

        【讨论】:

          【解决方案9】:

          怎么了

          import sys
          from os.path import dirname, abspath
          
          local_dir = abspath(dirname(__file__))
          sys.path.append(local_dir)
          
          import somescript
          

          或者最好还是将功能包装在一个函数中,例如baz,那就这样做吧。

          import sys
          from os.path import dirname, abspath
          
          local_dir = abspath(dirname(__file__))
          sys.path.append(local_dir)
          
          import somescript
          somescript.baz()
          

          似乎有很多脚本启动 python 进程或分叉,这是必需的吗?

          【讨论】:

            【解决方案10】:

            子进程调用是一个非常直观的系统调用。它可以用于任何通用过程...因此不知道如何自动处理 Python 脚本。

            试试

            call ('python somescript.py')
            

            如果这不起作用,您可能想尝试绝对路径,和/或检查 Python 脚本的权限......典型的有趣的东西。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2012-07-31
              • 1970-01-01
              • 1970-01-01
              • 2015-07-16
              • 1970-01-01
              • 2013-09-26
              • 2015-06-10
              • 1970-01-01
              相关资源
              最近更新 更多