如何读取argv值而不转义字符串?
我正在写一个叫flac2m4a的Python脚本,它会调用ffmpeg把.flac文件转换成.m4a文件。这个程序的核心部分是这样的:
cmd = "ffmpeg -i %s -acodec alac %s.m4a" % (sys.argv[1], sys.argv[1][:-5])
os.system(cmd)
我可以这样使用这个程序:
./flac2m4a path_to_the_song.flac
但是当我运行一些文件名中有特殊字符的歌曲时:
./flac4m4a.py Justin\ Bieber\ -\ Never\ Say\ Never\ -\ The\ Remixes/01\ -\ Never\ Say\ Never\ \(feat.\ Jaden\ Smith\).flac
在Linux系统下,当我按下Tab键进行自动补全时,特殊字符会被加上一个\
符号,但当我从sys.argv[1]
读取时,Python会把它们转换成普通字符串:
Justin Bieber - Never Say Never - The Remixes/01 - Never Say Never (feat. Jaden Smith).flac
所以我只是想知道如何准确地读取argv[1]
,让它和用户输入的一样(包括那些\
符号)。
3 个回答
./flac4m4a.py Justin\ Bieber\ -\ Never\ Say\ Never\ -\ The\ Remixes/01\ -\ Never\ Say\ Never\ (feat.\ Jaden\ Smith).flac
上面这个命令中的 '\' 是用来处理空格、括号等特殊字符的。简单来说,它的作用是让程序知道这些字符是文件名的一部分,而不是命令的分隔符。这样的话,命令就可以理解为:
./flac4m4a.py 'Justin Bieber - Never Say Never - The Remixes/01 - Never Say Never (feat. Jaden Smith).flac'
在你的 Python 程序中,argv[1] 这个参数是看不到 '\' 的,也就是说它不会把这些反斜杠当作字符来处理。
如果你真的需要在每个空格、括号前面加上 '\',你可以在你的 Python 程序里很简单地添加上去。
你问的问题实际上是不可能实现的,因为在命令行输入的内容在被处理时会丢失。命令行的处理程序会解析一些特殊字符,然后把处理后的结果传给Python。等到Python接收到这个字符串时,所有的特殊字符都已经被处理掉了,也就是说,这并不是bash的错误,而是bash(以及大多数其他命令行工具)的设计方式。
虽然你可以给字符串加上引号来让它在命令行中运行,但其实你根本不应该用命令行来执行你的命令,这样就不需要加引号了。建议使用 subprocess.call()
来代替 os.system()
:
subprocess.call(["ffmpeg", "-i", sys.argv[1], "-acodec", "alac",
sys.argv[1][:-5] + ".m4a"])