cat:写入错误:资源暂时不可用

问题描述 投票:0回答:1

我正在使用

cat
命令在 Azure Databricks Notebook 中使用
%sh
命令合并多个文件。我的
data_files
文件夹中有大约 1200 个 csv 文件,文件总大小约为 300 GB。当我运行下面的代码时,有时它会合并文件而没有任何错误,但有时会抛出错误
cat: write error: Resource temporarily unavailable
并且创建
output.txt
文件时没有任何数据。

err=$(cat /dbfs/mnt/devl/header_file/*.csv /dbfs/mnt/devl/data_files/*.csv 2>&1 > /dbfs/mnt/devl/output.txt)
RC=$?
if [ $RC -ne 0 ]; then
  echo "Error code : $RC"
  echo "Error msg : $err"
fi

谁能告诉我错误的根本原因是什么

cat: write error: Resource temporarily unavailable
以及如何解决这个问题?

bash shell sh databricks databricks-notebook
1个回答
0
投票

我无权访问 Azure,但如果我不得不猜测 - 您的问题与目标驱动器的写入速度有关。

解释

写入速度通常比读取速度低几倍,并且如果源文件足够大,应用程序可以读取的数据多于写入的数据,从而填充内核缓冲区。想象一根水管注满一个有小孔的水桶——最终它会被填满。现在,在这种情况下我们有两种不同的行为:

  1. 如果目标文件以阻塞模式打开,
    write
    调用将等待目标刷新足够的数据,然后恢复写入。
  2. 如果目标文件在阻塞模式下打开,
    write
    调用将失败(返回
    -1
    并将
    errno
    设置为
    EAGAIN
    EWOULDBLOCK
    )。这为客户端应用程序提供了很大的灵活性,特别是在多线程用例中 - 但需要显式处理此条件。

您正在使用

cat
,它似乎无法处理非阻塞模式 - 并且只会在
EAGAIN
上出错。

解决方法

我在 https://unix.stackexchange.com/questions/613117/cat-resource-temporarily-unavailable:

下的评论中看到了建议的解决方法
perl -MFcntl -e 'fcntl STDIN, F_SETFL, fcntl(STDIN, F_GETFL, 0) & ~O_NONBLOCK'

或者,您可以寻找一个做得更好的工具 - 或者编写您自己的实用程序。下面是一个小型 Python 脚本的示例,它可以完成您正在寻找的任务。请注意,我只在小文件上测试了它,所以 YMMV。

#!/usr/bin/env python3

import shutil
import os


def concatenate_files(src_filenames: list[str], dst_filename: str) -> None:
  with open(dst_filename, 'wb') as outfile:
    for infile_name in src_filenames:
      with open(infile_name, 'rb') as infile:
        shutil.copyfileobj(infile, outfile)
      outfile.flush()
      os.fsync(outfile.fileno())


if __name__ == "__main__":
  # Take command line argument to make it actually useful
  input_files = ['file1.dat', 'file2.dat', 'file3.dat']
  output_file = 'result.dat'
  concatenate_files(input_files, output_file)
© www.soinside.com 2019 - 2024. All rights reserved.