python win subprocess模块popen 如何开启关闭新控制台/使用管道及关闭子进程(ffmpeg相关)

  • 使用python的subprocess模块(windows环境下)

    1. 如何调用ffmpeg并作为守护进程(支持ffmpeg命令中使用管道)

      1. 在新控制台/新窗口里显示(但无法在新控制台里输入)

        process = subprocess.Popen('cmd', creationflags=subprocess.CREATE_NEW_CONSOLE, stdin=subprocess.PIPE)
        process.stdin.write(('%s\n' % ffmpeg_cmd).encode('utf-8'))
        #往控制台里写入ffmpeg命令
        #这样执行完ffmpeg命令不会退出,想要调用完自动退出要使用('%s&exit\n' % ffmpeg_cmd)
        process.stdin.flush()

      2. 不显示新控制台/新窗口

        process = subprocess.Popen(ffmpeg_cmd, shell=True, creationflags=subprocess.CREATE_NEW_CONSOLE)

    2. 如何调用ffmpeg不作为守护进程,随python程序结束(支持ffmpeg命令中使用管道)

      • 复制上面的的命令,去掉creationflags参数,并加上stderr=subprocess.DEVNULL,例如:

        process = subprocess.Popen(ffmpeg_cmd, shell=True, stderr=subprocess.DEVNULL)
        #stderr=subprocess.DEVNULL是为了隐藏ffmpeg命令产生的输出,因为ffmpeg将日志都输出在stderr上
        #如果不重定向至subprocess.DEVNULL,就会直接输出在python程序所在的控制台上,造成混乱

    3. 如何结束/杀掉/终结调用的ffmpeg进程

      1. python的signal模块: os.kill(process.pid, signal.CTRL_C_EVENT),但泛用性小,不推荐
      2. linux下
        • 使用"进程组",相关教程附在《拓展参考》内
      3. windows下
        • windows的taskkill命令

          os.system("taskkill /t /f /pid %s" % process.pid)
          #/t:结束进程树,包括子进程 /f:强制结束 /pid:进程pid
          #可使用其他命令替代os.system

          1. 为何可以使用系统管道?
            • 因为在命令行环境下使用系统管道
            • 所以用Popen('cmd')开启cmd进程,往cmd里写入ffmpeg命令,就可以在命令行环境下使用系统管道
            • 或者shell=True,会开启一个命令行执行命令
            • 可应用于ffmpeg转码给ffplay播放
            • 此处关于shell=True的解释并不准确,详情参考官方文档及各类教程
          2. 为何process.kill()/terminate()无法结束ffmpeg进程?
            • 因为process对应的是执行ffmpeg命令的命令行进程,所以popen返回的pid实际是命令行shell环境的pid
            • 调用kill()只会结束命令行进程而无法结束ffmpeg进程
            • subprocess模块无法结束调用产生的子进程是个大坑,不过耐心搜索还是能找到对应方案
          3. 关于开启新控制台/新窗口,以及上文中使用Popen的相关参数
            • 请参考有关教程,例如以下参数:
            • stdin/stdout/stderr,subprocess.PIPE/DEVNULL/STDOUT
            • shell=True/False
            • creationflags=subprocess.CREATE_NEW_CONSOLE/CREATE_NEW_PROCESS_GROUP
            • 坑爹的startupinfo
  • 参考
  • 拓展参考
    1. 类似的popen调用ffmpeg的情况
    2. CTRL C 信号结束进程
    3. 关于使用popen无法结束子进程的坑
    4. startupinfo相关MSDN文档出处
    5. startupinfo相关
  • 总结对popen打开新终端窗口调用ffmpeg的理解:
    • shell参数默认是False,就是不调用命令行环境解释popen中的命令,效果就是popen中的整条命令当作调用某个具体的程序,所以管道符号被当作程序的参数对待,而没有发挥管道的作用。在这里popen的命令是'cmd'打开终端程序,但是要出现新的终端窗口就要creationflags参数的配合。
    • 当不设置creationflags的时候,popen执行的命令产生的子进程依附于python脚本下,而python脚本依附于终端窗口下(如果是在终端里执行的python脚本),所以子进程和python脚本共享一个终端窗口,所以输出信息会混在一起。当creationflags设置为CREATE_NEW_CONSOLE时,子进程会独立于python脚本,自然就不会共享同一个终端窗口了,配合'cmd'命令,就打开了一个新的独立终端窗口,即使python脚本关闭了,子进程也不会受影响,大概可以算是'守护进程'吧?
    • 这么说的话,直接调用ffmpeg命令岂不是也能产生新的终端窗口?行不行我不记得了,但我需要用到管道符号,所以shell=False的情况下是无法实现的。
    • 那让shell=True不就好了?实验证明这种组合的话,是无法产生新窗口的,现在回想起来我就是被这样的组合坑了良久却百思不得其解为什么没有新窗口。具体原因不知道是什么也不做探究了。
    • 结论是CREATE_NEW_CONSOLE的效果是产生独立的子进程,shell=True是以命令行环境执行命令,两者一起用会无法产生新终端窗口,但运行正常,子进程不会输出在python终端里。
  • python win subprocess模块popen 如何开启关闭新控制台/使用管道及关闭子进程(ffmpeg相关) 结论 使用python的subprocess模块(windows环境下) 如何调用ffmpeg并作为守护进程(支持ffmpeg命令中使用管道) 在新控制台/新窗口里显示(但无法在新控制台里输入) process = subprocess.Popen('cmd', creationflags=subprocess.CREA
    本来收集整理网络上 相关 资料后整理: 从 python 2.4版本开始,可以用 subprocess 这个 模块 来产生 子进程 ,并连接到 子进程 的标准输入/输出/错误中去,还可以得到 子进程 的返回值。 subprocess 意在替代其他几个老的 模块 或者函数,比如:os.system os.spawn* os. popen * popen 2.* commands.* 一、 subprocess ...
    print("process is dead") def monitor(process1,onexit):     print("process id %s waiting"% (process1.pid))     proces
    subprocess . Popen (): 在一些复杂场景中,我们需要将一个进程的执行输出作为另一个进程的输入。在另一些场景中,我们需要先进入到某个输入环境,然后再执行一系列的指令等。这个时候我们就需要 使用 到suprocess的 Popen ()方法。该方法有以下参数: args:shell命令,可以是字符串,或者序列类型,如list,tuple。 bufsize:缓冲区大小,可不用关心 stdi...
    ## call date command ## p = subprocess . Popen ("date /t", stdout= subprocess .PIPE, shell=True) (output, err) = p.communicate() p_status = p.wait() print("Command output : ", output.decode('gbk')) print("Command exit status/return code : ",.
    你可以 使用 此句柄终止 使用 ctypes或py win 32扩展名的 子进程 。 # Create a process that won't end on its own import subprocess process = subprocess . Popen ([' python .exe', '-c', 'while 1: pass']) # Kill the process using py win 32 # 执行外部shell命令, 输出结果输出 管道 p = subprocess . Popen (cmd, shell=True, stdout= subprocess .PIPE, stderr= subprocess .STDOUT) p.wait() # 从标准输出读出shell命令的输出结果 #rt = p.stdout.read().decode()
    win dows下 python subprocess . Popen 执行adb 命令进程无法终止 logcmd = "adb logcat -v time > C:/log.txt" self. Popen = subprocess . Popen (logcmd,stdout = subprocess .PIPE,shell=True) 用上面的方法来获取logcat的信息,它的实际原理是另外 开启 一个cmd命令来运行adb logcat的命令,即使后面用 popen .terminate()也只能 关闭 cmd的命.
    ffmpeg 是一个强大的开源命令行多媒体处理工具。关于 ffmpeg 的安装问题,可以看之前发的《 ffmpeg 的安装和简单 使用 》。 ffmpeg 如此强大,那么能不能用 python 调用并实现它的所有功能呢,答案自然是肯定的。 要实现在 python 中调用 ffmpeg ,需要了解一下 subprocess 模块 。简单来说, subprocess 模块 就相当于一个包壳的命令行,原则上可以在命令行中实现的事情都可以 使用 su...
    可以 使用 Popen 对象的wait()方法来等待 子进程 的执行完成,并返回 子进程 的退出状态码。如果 子进程 成功执行,wait()方法返回0,否则返回一个非零值。示例代码如下: ``` python import subprocess # 执行命令 p = subprocess . Popen (['ls', '-l']) # 等待命令执行完成并获取返回值 returncode = p.wait() if returncode == 0: print('命令执行成功') else: print('命令执行失败') 在这个例子中,我们 使用 subprocess 模块 执行了一个简单的ls命令,然后 使用 Popen 对象的wait()方法等待命令执行完成,并获取返回值。如果返回值为0,则说明命令执行成功,否则说明命令执行失败。
    bind-address=0.0.0.0 # 设置mysql的安装目录,即你解压缩安装包的位置 basedir=E:\MySQL-8.0.13\mysql-8.0.13-winx64 # 设置mysql数据库的数据的存放目录 datadir=E:\MySQL-8.0.13\mysql-8.0.13-winx64/data # 设置端口号 port=3306 # 允许最大连接数 max_connections=200 # 开启查询缓存 explicit_defaults_for_timestamp=true # 创建表使用的默认存储引擎 default-storage-engine=INNODB # 设置服务端的默认字符集 character-set-server=utf8 [mysql] # 设置mysql客户端默认字符集 default-character-set=utf8 [/code]