Warm tip: This article is reproduced from serverfault.com, please click

python-Linux中“ find”命令中的子进程stdout readline()编码错误

(python - subprocess stdout readline() encoding error in "find" command in linux)

发布于 2020-11-29 17:40:25

我已经提到了关于同一错误的其他问题。但是我不想指定编码,只想跳到下一行。是否可以ignore errorsreadline()旁边看?

我正在使用find实用程序来获取30天以上的文件。并返回具有完整路径的文件。但是,当另一个用户将代码用于另一条路径时,他得到了编码错误。因此,如果有错误,stdout.readline()则我想跳过该行,然后移至下一个。是否stdout.readline()允许跳过错误之类的东西?

同样在这种给定的find结果场景中,我可以使用utf-8编码并确保将读取的路径没有错误吗?

find_cmd = ['find', '/a/b', '-mtime', f'+30', '-readable', '-type', 'f', '-print']
j = ' '.join(find_cmd)
proc = subprocess.Popen(j, universal_newlines=True, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

while True:
  file = proc.stdout.readline().replace('\n', '') #Error here 'utf-8' codec can't decode byte 0xe4 in position 1478: invalid continuation byte
  if not file: break
  movefile(file)
Questioner
sjd
Viewed
0
tripleee 2020-12-01 01:11:27

如果find不能保证来自的输出为UTF-8,请不要使用universal_newlines=True(又名text=TruePython 3.7及更高版本)。

你可以选择在阅读时进行解码,如果需要的话,可以跳过无效的UTF-8条目。

另外,出于对的热爱$dmr,请勿join仅将你的最佳列表放在一起,以免不必要地浪费在shell=True列表上。

最后,如果你不想让错误消息像文件名一样出现,请不要重定向stderr根本就不要完全重定向,以使其在控制台上显示,或者如果要完全丢弃它们直接指向stdoutfindstderrstderrsubprocess.DEVNULL

find_cmd = [
    'find', '/a/b', '-mtime', f'+30', '-readable',
    '-type', 'f', '-print']
proc = subprocess.Popen(find_cmd, stdout=subprocess.PIPE, check=True)

while True:
  filename = proc.stdout.readline().replace(b'\n', b'')
  if not filename:
    break
  try:
    file = filename.decode('utf-8')
    movefile(file)
  except UnicodeDecodeError:
    logging.info('Skipping non-UTF8 filename %r' % filename)

你会注意到我添加check=Truesubprocess.Popen()如果你想忽略find故障,也许可以再解决一次。