我想迭代文件夹中的一些文件,并将文件的路径发送到列表。然后我想将此列表传递给子进程以执行bash命令:
procfiles = []
os.chdir("/path/to/directory")
for root, dirs, files in os.walk('.'):
for file in files:
if '.mp3' in file:
filename = os.path.join(root, file)
print(filename)
procfiles.append(filename)
print(procfiles)
args = [command, with, arguments].extend(procfiles)
process = subprocess.Popen(args, shell=False)
output, error = process.communicate()
但是当文件包含德语变音字母时,我得到以下输出。例如:ä,ö或ü
./titleWith ä or ü - artist with ü.mp3 #print(filename)
['./titleWith \udcc3\udca4 or \udcc3\udcbc - artist with \udcc3\udcbc.mp3'] #print(procfiles)
这意味着在编码期间编码有问题
procfiles.append(filename)
进程,对吧?
之后,子进程失败并显示错误:
UnicodeEncodeError:'utf-8'编解码器无法编码字符'\ udcc3' 第43位:代理人不被允许
的相关信息:
更新
我刚注意到,当我使用用户 root 或 www-data 手动执行它时,它可以工作,但当我通过我的自定义php执行它时脚本(它只有一个shell_exec('/usr/bin/python3 /path/to/script.py >> /path/to/log.log 2>&1')
)它不起作用。
这不应该与我手动从用户www-data执行时相同吗?或者,当从PHP脚本执行python脚本时,是否设置了其他一些环境变量?
答案 0 :(得分:0)
这是完全预期的行为,尽管在您的情况下文件系统编码是错误的,因此它输出代理转义以正确地重新编码您的字符串。
反斜杠转义只是字符串的精确表示。
如果您想正确打印字符(尽管这取决于您的sys.stdout
和终端的编码),请在每个字符串上调用print()
。似乎子流程未将errors=surrogateescape
传递给str.encode()
。
答案 1 :(得分:0)
如果我运行此脚本:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os
import subprocess
procfiles = []
os.chdir("/home/dede/tmp/")
for root, dirs, files in os.walk('.'):
for file in files:
if '.mp3' in file:
filename = os.path.join(root, file)
print(filename)
procfiles.append(filename)
print(procfiles)
args=["ls", "-la"]
args.extend(procfiles)
process = subprocess.Popen(args, shell=False)
output, error = process.communicate()
我得到了这个输出:
dede@i5:~> python3 tst.py
./Leere Datei.mp3
./Kopie ä von Leere Datei.mp3
['./Leere Datei.mp3', './Kopie ä von Leere Datei.mp3']
-rw-r--r-- 1 dede users 6 31. Mär 16:50 ./Kopie ä von Leere Datei.mp3
-rw-r--r-- 1 dede users 6 31. Mär 16:50 ./Leere Datei.mp3
所以错误的部分必须在你的代码中的其他地方......
...或者你的mp3在Windows编码中有 Umlaute 。
答案 2 :(得分:0)
<强> Python3.5 强>
首先转换字符串:
procfiles = [s.encode('utf-8', errors='surrogateescape').decode('utf-8')
for s in procfiles]
Python 3.6
您可以使用errors='surrogateescape'
指定忽略此错误:
process = subprocess.Popen(args, shell=False, errors='surrogateescape')