附加列出功能编码错误的umlauts



我想通过文件夹中的某些文件迭代,然后将文件路径发送到列表。然后,我想将此列表传递给子过程以执行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()

但是,当文件包含德语Umlauts字母时,我会得到以下输出。例如:ä,Ö或ü

./titleWith ä or ü - artist with ü.mp3                                         #print(filename)
['./titleWith udcc3udca4 or udcc3udcbc - artist with udcc3udcbc.mp3']    #print(procfiles)

这意味着编码在 procfiles.append(filename)进程,对吧?

之后,子过程失败了,错误:

unicodeCodeError:'utf-8'编解码器无法编码字符' udcc3' 位置43:不允许替代

infos:

  • python 3.5.3
  • OS:Debian Jessie
  • 内核:4.9.58
  • 建筑:ARMHF

更新:

我只是注意到,当我用用户手动执行它时脚本(仅是shell_exec('/usr/bin/python3 /path/to/script.py >> /path/to/log.log 2>&1')(它不起作用。

这与我从用户www-data手动执行时不应该一样吗?还是从PHP脚本执行Python脚本时设置了其他一些环境变量?

这是确切的预期行为,尽管在您的情况下,文件系统编码错误,因此它输出替代逃脱以正确重新编码字符串。后斜线逃脱只是字符串的确切表示。如果您想正确打印字符(尽管这取决于sys.stdout和终端的编码(,请在每个字符串上调用print()。似乎子过程没有将errors=surrogateescape传递给str.encode()

如果我运行此脚本:

#!/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-insoding中具有 umlaute

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')

最新更新