首页 > 解决方案 > linux中“find”命令中的子进程stdout readline()编码错误

问题描述

我已经提到了有关同一错误的其他问题。但我不想指定编码,只想跳到下一行。是否可以进入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)

标签: pythonsubprocessfind

解决方案


如果find不能保证输出为 UTF-8,请不要使用universal_newlines=True(也就是text=True从 Python 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失败,也许再把它拿出来。


推荐阅读