【问题标题】:How to call a shell script from python code?如何从 python 代码调用 shell 脚本?
【发布时间】:2011-04-16 04:37:23
【问题描述】:

如何从python代码调用shell脚本?

【问题讨论】:

    标签: python shell


    【解决方案1】:

    subprocess 模块将为您提供帮助。

    明显微不足道的例子:

    >>> import subprocess
    >>> subprocess.call(['sh', './test.sh']) # Thanks @Jim Dennis for suggesting the []
    0 
    >>> 
    

    test.sh 是一个简单的 shell 脚本,0 是它的运行返回值。

    【讨论】:

    • 注意:最好将 subprocess.call() 传递给列表而不是字符串(有关示例和原因,请参见下面的 Hugo24 命令)。
    • 这给出:OSError: [Errno 13] Permission denied。我的脚本不需要使用 sudo 运行。 @Manoj Govindan
    • 带参数:subprocess.call(['./test.sh', 'param1', 'param2'])
    • @alper 转到您放置脚本的文件夹并运行命令chmod +x script.sh。注意:script.sh 是您的脚本的占位符,请相应地替换它。
    • python 3.5 中子进程 api 发生了变化。新方法是 .run(args) 而不是 call
    【解决方案2】:

    有一些方法可以使用os.popen()(已弃用)或整个subprocess 模块,但this approach

    import os
    os.system(command)
    

    是最简单的一种。

    【讨论】:

    • 为什么这不是最受好评的答案?不必导入模块不是更好的解决方案吗?这里一定有什么缺点吧?
    • 使用subprocess,您可以管理输入/输出/错误管道。当你有很多参数时也更好——使用os.command(),你必须创建带有转义特殊字符的整个命令行,使用subprocess,有简单的参数列表。但对于简单的任务,os.command() 可能就足够了。
    • 引用该链接:The subprocess module provides more powerful facilities for spawning new processes and retrieving their results; *using that module is preferable to using this function.*
    【解决方案3】:

    如果你想将一些参数传递给你的shell脚本,你可以使用shlex.split()的方法:

    import subprocess
    import shlex
    subprocess.call(shlex.split('./test.sh param1 param2'))
    

    test.sh 在同一文件夹中:

    #!/bin/sh
    echo $1
    echo $2
    exit 0
    

    输出:

    $ python test.py 
    param1
    param2
    

    【讨论】:

    • 这很优雅。
    • 如何将python变量作为参数传递?
    • @keerthi007 subprocess.call(shlex.split(f"./test.sh param1 {your_python_var} param3"))
    【解决方案4】:
    import os
    import sys
    

    假设 test.sh 是您想要执行的 shell 脚本

    os.system("sh test.sh")
    

    【讨论】:

      【解决方案5】:

      我正在运行 python 3.5 并且 subprocess.call(['./test.sh']) 对我不起作用。

      我给你三个解决方案取决于你想对输出做什么。

      1 - 调用脚本。您将在终端中看到输出。输出是一个数字。

      import subprocess 
      output = subprocess.call(['test.sh'])
      

      2 - 调用并将执行和错误转储到字符串中。除非您打印(标准输出),否则您不会在终端中看到执行。 Shell=True 作为 Popen 中的参数对我不起作用。

      import subprocess
      from subprocess import Popen, PIPE
      
      session = subprocess.Popen(['test.sh'], stdout=PIPE, stderr=PIPE)
      stdout, stderr = session.communicate()
      
      if stderr:
          raise Exception("Error "+str(stderr))
      

      3 - 调用脚本并将 temp.txt 的 echo 命令转储到 temp_file 中

      import subprocess
      temp_file = open("temp.txt",'w')
      subprocess.call([executable], stdout=temp_file)
      with open("temp.txt",'r') as file:
          output = file.read()
      print(output)
      

      别忘了看看doc subprocess

      【讨论】:

      • 注意不要将 stdout=PIPE 或 stderr=PIPE 与 subprocess.call 一起使用。如果子进程生成足够的输出到管道以填满操作系统管道缓冲区,则子进程将阻塞,因为管道没有被读取。
      【解决方案6】:

      使用上面提到的子进程模块。

      我是这样使用的:

      subprocess.call(["notepad"])
      

      【讨论】:

      • 注意:使用列表调用 subprocess 更安全,因为它不需要通过 shell 传递(可能未经处理的)字符串以进行解析/解释。列表中的第一项将是可执行文件,所有其他项将作为参数传递。
      【解决方案7】:

      我知道这是一个老问题,但我最近偶然发现了这个问题,它最终误导了我,因为自 python 3.5 以来Subprocess API 发生了变化。

      执行外部脚本的新方法是使用run 函数,它运行args 描述的命令。等待命令完成,然后返回 CompletedProcess 实例。

      import subprocess
      
      subprocess.run(['./test.sh'])
      

      【讨论】:

        【解决方案8】:

        如果脚本有多个参数

        #!/usr/bin/python
        
        import subprocess
        output = subprocess.call(["./test.sh","xyz","1234"])
        print output
        

        输出会给出状态码。如果脚本成功运行,它将给出 0 否则为非零整数。

        podname=xyz  serial=1234
        0
        

        下面是 test.sh shell 脚本。

        #!/bin/bash
        
        podname=$1
        serial=$2
        echo "podname=$podname  serial=$serial"
        

        【讨论】:

          【解决方案9】:

          子进程模块是启动子进程的好模块。 您可以使用它来调用 shell 命令,如下所示:

          subprocess.call(["ls","-l"]);
          #basic syntax
          #subprocess.call(args, *)
          

          你可以查看它的文档here.

          如果您的脚本写在某个 .sh 文件或长字符串中,那么您可以使用 os.system 模块。调用起来相当简单易行:

          import os
          os.system("your command here")
          # or
          os.system('sh file.sh')
          

          此命令将运行脚本一次,直到完成,并阻塞直到它退出。

          【讨论】:

          • 你不是也要导入sys吗?
          • 不,你没有;尝试打开一个 Python shell 并运行这个 sn-p
          • 嗨 Ankit。我需要一些帮助。假设 example.sh 文件位于 Oracle 云基础架构中。如何在 python 中调用/运行这样的 example.sh 文件?那么我需要连接到oracle云,我应该使用你在这里编写的脚本。您能否编写附加代码(如何连接 OCI 中的 example.sh 文件)?谢谢。
          【解决方案10】:

          子流程很好,但有些人可能更喜欢scriptine。 Scriptine 有更多高级方法集,例如 shell.call(args)path.rename(new_name)path.move(src,dst)。 Scriptine 基于subprocess 等。

          scriptine 的两个缺点:

          • 当前的文档级别会更全面,即使它已经足够了。
          • 与 subprocess 不同,目前默认不安装 scriptine 包。

          【讨论】:

            【解决方案11】:

            如果您的 shell 脚本文件没有执行权限,请按以下方式执行。

            import subprocess
            subprocess.run(['/bin/bash', './test.sh'])
            

            【讨论】:

              【解决方案12】:

              请尝试以下代码:

              Import Execute 
              
              Execute("zbx_control.sh")
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2019-12-29
                • 2018-03-25
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2013-01-04
                相关资源
                最近更新 更多