【已解决】Python的坑:os.system()运行带有空格的长路径和双引号参数有bug

news2025/7/5 14:27:24

在Python代码里运行DOS命令,可以使用os库的os.system()函数。其用法很简单,需要注意的是os.system不会返回输出的结果赋予一个变量。今天我发现了一个bug:当DOS命令行带有双引号路径、双引号参数时,os.system()运行的结果总是显示:“XXX(路径名) 不是内部或外部命令,也不是可运行的程序或批处理文件。”

我写了一个Python批量使用ffmpeg转换视频的代码。首先定义ffmpeg的路径:

ffmpeg_path = r'D:\Program Files\ffmpeg\bin\ffmpeg.exe'

当运行os.system(ffmpeg_path)会报错,这样写是入门时经常遇到的现象。

3961c0b4d3d64ca4845a3e558f3ef3c3.png

很显然路径名称中的Program Files含有空格,DOS要求凡是有空格的路径一定要加双引号,因此代码要这样改才能使os.system()正确执行:

ffmpeg_path = r'"D:\Program Files\ffmpeg\bin\ffmpeg.exe"'

今天我要讲的重点不是这个。

ffmpeg需要添加很多参数来转码,比如把ts格式的m3u8文件转换成mp4文件:ffmpeg -allowed_extensions ALL -protocol_whitelist "file,http,https,crypto,tcp" -i "input.m3u8" -c copy "output.mp4"。

import os
inputfile = r'd:\temp\input.m3u8'
outputfile = r'd:\temp\output.mp4'
ffmpeg_path = r'"D:\Program Files\ffmpeg\bin\ffmpeg.exe"'
command = f'{ffmpeg_path} -allowed_extensions ALL -protocol_whitelist "file,http,https,crypto,tcp" -i "{inputfile}" -c copy "{outputfile}"'

'''
print(command)
输出:
"D:\Program Files\ffmpeg\bin\ffmpeg.exe" -allowed_extensions ALL -protocol_whitelist "file,http,https,crypto,tcp" -i "d:\temp\input.m3u8" -c copy "d:\temp\output.mp4"
'''

os.system(command)

这里的command字符串明明没问题,但到了os.system(command)又出同样的错:

 

我意识到又是双引号的问题了。如果去掉ffmpeg后面所有的参数、仅运行主程序呢?试试:os.system(ffmpeg_path)

e23cd73376934d2d942af1007c3752b5.png

结果是可以正常运行。是不是ffmpeg参数带有双引号就运行不了?

可是ffmpeg规定-protocol_whitelist 参数后面的类型 "file,http,https,crypto,tcp" 必须有双引号,改单引号或去掉都非法。-i 后的输入文件路径、以及末尾的输出文件路径如有空格,也必须加双引号。

前后调试了多次,我发现如果ffmpeg不加上完整的路径,os.system(command)可以成功运行。但需要作前提设置:要把ffmpeg的路径添加到系统路径的变量里(具体操作不作赘述)。

按照这个思路顺藤摸瓜,既然参数的双引号一定要加,那么主程序的路径名不加双引号,怎么操作?我突发奇想:ffmpeg的路径使用旧式的8位字符短路径又如何?把长路径中的“Program Files”改为“Progra~1”,代码改成这样:

inputfile = r'd:\temp\input.m3u8'
outputfile = r'd:\temp\output.mp4'
ffmpeg_path = r'D:\Progra~1\ffmpeg\bin\ffmpeg.exe'
command = f'{ffmpeg_path} -allowed_extensions ALL -protocol_whitelist "file,http,https,crypto,tcp" -i "{inputfile}" -c copy "{outputfile}"'

os.system(command)

意想不到的是os.system(command)居然成功运行了。ffmpeg转码的信息在屏幕里不停滚动,像瀑布一样哗哗直流。

b5ff50d5d3d643a395793ac4df875ac9.png

“Progra~1”这种短路径表示方式可以说是Windows系统的绝对路径,能彻底访问含空格、或带奇怪字符的路径,这是多年前Win9x年代的玩法,现在还有多少人记得?方法虽旧,但却很管用。

小结一下:os.system()的bug在于:

条件1:当命令行的主程序路径含有空格时,路径必须有双引号。

条件2:命令行的参数带有双引号。

这两个条件都满足的情况下,运行会报错:“XXX(路径名) 不是内部或外部命令,也不是可运行的程序或批处理文件。”

我当前的Python版本是3.10,也许os.system()函数没有考虑周全像DOS命令行参数带双引号这种情况。

解决办法:

1、主程序的路径改用旧式的8位字符短路径,并且去掉其双引号。后面的参数保留双引号,不用改。

或者

2、把主程序所在的路径添加到Windows系统的环境变量%PATH%,os.system()就可以直接使用程序名称,不需要添加路径名。

以上的小结有点啰嗦,我作个通俗一点的表格归纳一下使用os.system()运行ffmpeg成功与否的组合搭配:

序号程序名参数结果
(1)带长路径程序名"参数"路径缺双引号,报错
(2)"带长路径程序名""参数"路径和参数都带双引号却报错。我认为是BUG。
(3)"带长路径程序名"参数参数不带双引号,如果程序对某些参数不要求带双引号就能正常运行,否则会报错。
(4)"带长路径程序名"可以运行,但没有参数,运行程序可能达不到预期的效果。
(5)程序名"参数"程序名前没有路径,程序必须在当前路径或者在系统%PATH%变量中才能成功,否则报错。
(6)短路径的程序名"参数"成功。短路径的程序名不需要加双引号了。

最后再教一招:如何获取短路径?

方法1:在cmd命令提示符下用 dir /x 命令查看。

方法2:Python代码引入win32api的GetShortPathName函数进行获取:

from win32api import GetShortPathName
ffmpeg_path = r'D:\Program Files\ffmpeg\bin\ffmpeg.exe'
ffmpeg_path = GetShortPathName(ffmpeg_path)
'''
print(ffmpeg_path)
输出:
'D:\Progra~1\ffmpeg\bin\ffmpeg.exe'
'''

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/402192.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

带你认识什么是485通信

在现代工业控制系统中,常常需要实现分布式控制,而分布式控制需要实现不同设备之间的通信。其中,485通信协议是一种被广泛使用的通信协议之一。1. 介绍A. 485通信的定义485通信协议是一种串行通信协议,也被称为RS-485。它是由美国电…

300. 最长递增子序列——【Leetcode每日刷题】

300. 最长递增子序列 给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。 子序列 是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子…

leetcode 1648. 销售价值减少的颜色球

1648. 销售价值减少的颜色球这道题不知为何总想记录下来,思路很简单,但是实现总是出错,这也许就是要记录的原因。再一个觉得题解写的比较难以理解,所以再细致一些解析。希望可以帮到实在搞不懂的同学 思路: 目的:我们…

聚观早报|谷歌发布最大视觉语言模型;王兴投资王慧文ChatGPT项目

今日要闻:谷歌发布全球最大视觉语言模型;马斯克预计Twitter下季度现金流转正;王兴投资王慧文ChatGPT项目;美国拟明年 11 月开展载人绕月飞行;慧与科技宣布收购Athonet谷歌发布全球最大视觉语言模型 近日,来…

RocketMQ重复消费的症状以及解决方案

RocketMQ重复消费的症状以及解决方案 生产消息时重复 症状 当一条消息已被成功发送到 消费者 并完成持久化,此时出现了网络闪断或者客户端宕机,导致服务端对客户端应答失败。 如果此时 生产者 意识到消息发送失败并尝试再次发送消息,消费者…

学习 Python 之 Pygame 开发魂斗罗(十一)

学习 Python 之 Pygame 开发魂斗罗(十一)继续编写魂斗罗1. 改写主类函数中的代码顺序2. 修改玩家初始化3. 显示玩家生命值4. 设置玩家碰到敌人死亡5. 设置敌人子弹击中玩家6. 修改updatePlayerPosition()函数逻辑继续编写魂斗罗 在上次的博客学习 Pytho…

【Flutter从入门到入坑】Flutter 知识体系

学习 Flutter 需要掌握哪些知识? 终端设备越来越碎片化,需要支持的操作系统越来越多,从研发效率和维护成本综合考虑,跨平台开发一定是未来大前端的趋势,我们应该拥抱变化。而 Flutter 提供了一套彻底的移动跨平台方案…

【AlgorithmTraining】06:STL容器使用与练习(上)

STL容器的使用与练习(上) OVERVIEWSTL容器的使用与练习(上)string类1.vector动态数组:(1)vector动态一维数组:(2)vector动态二维数组:2.deque双端…

VR全景旅游,成为数字文旅破局关键!

导语:VR全景技术是一种基于虚拟现实技术的全景图像显示技术,已经在各个领域得到广泛应用。在旅游业中,VR全景技术也越来越受到重视,并逐渐成为旅游业发展的重要趋势。本文将介绍VR全景技术在旅游业中的应用场景和价值,…

【嵌入式Linux内核驱动】02_字符设备驱动

字符设备驱动 〇、基本知识 设备驱动分类 (按共性分类方便管理) 1.字符设备驱动 字符设备指那些必须按字节流传输,以串行顺序依次进行访问的设备。它们是我们日常最常见的驱动了,像鼠标、键盘、打印机、触摸屏,还有…

MATLAB——信号的采样与恢复

**题目:**已知一个连续时间信号 其中:f01HZ,取最高有限带宽频率fm5f0。分别显示原连续时间信号波形和 3种情况下抽样信号的波形。并画出它们的幅频特性曲线,并对采样后的信号进行恢复。 step1.绘制出采样信号 这部分相对简单…

面试知识点梳理及相关面试题(十一)-- docker

1. Docker和虚拟机的区别 容器不需要捆绑一整套操作系统,它只需要满足软件运行的最小内核就行了。 传统虚拟机技术是虚拟出一整套硬件后,在其上运行一个完成操作系统,在该系统上再运行所需应用进程容器内的应用进程直接运行于宿主的内核&am…

TCP

TCP 流量控制 一般来说,我们希望数据传输的快一些,但如果对方把数据发送的过快,接收方就可能来不及接收,这就会造成数据的丢失 流量控制就是让发送方的发送速率不要太快,让接收方来得及接收 利用滑动窗口机制可以在TCP连接上实现对发送方的流量控制 TCP接收方利用自己的接收…

青岛OJ(QingdaoU/OnlineJudge)部署如何直连数据库批量修改

1.postgres数据库QingdaoU/OnlineJudge用的数据库是postgreSQL,一个关系型数据库。默认端口是5432,我们下载一个navcat 15以上的版本,用来连数据库。2.修改docker-compose.yml文件修改docker-compose.yml,手动添加一个端口&#x…

一三四——一六七

一三四、JavaScript——_DOM简介 MDNq前端参考文档&#xff1a;DOM 概述 - Web API 接口参考 | MDN (mozilla.org) 一三五、JavaScript——HelloWorld <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta h…

【JSON文件解析】JSON文件

文章目录概要&#xff1a;本期主要介绍Qt解析JSON数据格式文件的方式。一、JSON数据格式1.JSON类似于XML&#xff0c;在JSON文件中&#xff0c;有且只有一个根节点2.JSON有两种主流包含型构造字符&#xff1a;{对象}、[数组]3.JSON的值主要包括&#xff1a;对象、数组、数字、字…

你还在调戏AI,有的公司已经用ChatGPT开展业务了

近日&#xff0c;OpenAI 正式宣布开放 ChatGPT 和 Whisper 两个模型的 API&#xff0c;API 版本的ChatGPT 不仅功能更多、性能更强&#xff0c;而且还更便宜一一相当于目前 GPT-3 模型价格打一折!划重点OpenAl正式开放 ChatGPT 和 Whisper 模型的 API&#xff0c;目前 SnapChat…

运营商大数据的发展现状和趋势

互联网时代&#xff0c;流量困局始终是困扰企业的一大难题。信息杂&#xff0c;无效投入多&#xff0c;商业性营销色彩浓厚&#xff0c;都在企业和客户之间树立起一层层厚厚的障壁。选择优秀的营销手段&#xff0c;对于一个企业来说至关重要&#xff0c;反之&#xff0c;如若在…

[2.2.4]进程管理——FCFS、SJF、HRRN调度算法

文章目录第二章 进程管理FCFS、SJF、HRRN调度算法&#xff08;一&#xff09;先来先服务&#xff08;FCFS, First Come First Serve&#xff09;&#xff08;二&#xff09;短作业优先&#xff08;SJF, Shortest Job First&#xff09;对FCFS和SJF两种算法的思考&#xff08;三…

Go语言之条件判断循环语句(if-else、switch-case、for、goto、break、continue)

一、if-else条件判断语句 Go中的if-else条件判断语句跟C差不多。但是需要注意的是&#xff0c;Go中强制规定&#xff0c;关键字if和else之后的左边的花括号"{“必须和关键字在同一行&#xff0c;若使用了else if结构&#xff0c;则前段代码快的右花括号”}"必须和关…