尝试将输出重定向到多个文件时如何解决“tee:打开的文件太多”

尝试将输出重定向到多个文件时如何解决“tee:打开的文件太多”

我需要json从存储在csv.由于不可能手动执行此操作,因此我编写了一个简短的 bash 脚本,使用 Python 逐个读取 URL 并将其传递给curl下载。此外,借助 的帮助tee,该脚本将下载的数据保存在文件中,并用标准代码命名每个文件。代码存储在同一文件夹中csv,文件存储在名为“Data”的单独文件夹中:

output_dir=Data
python pass_urls_to_std_out.py | xargs curl -k | tee $output_dir/$(python pass_cd_to_std_out.py) > /dev/null

pass_urls_to_std_out.py只是一个简短的 Python 脚本,它读取 url 并将它们一一传递到标准输出。

pass_cd_to_std_out.py是一个类似的脚本,它只是一个接一个地读取代码。

> /dev/null用于避免打印屏幕上tee的所有输出。curl

不幸的是,该脚本对于小型文件集运行良好,但是当我尝试下载的文件数量增加时,我收到以下错误消息:

tee: 4208005.json: Too many open files
tee: 4110607.json: Too many open files
tee: 4304903.json: Too many open files
tee: 4217303.json: Too many open files
tee: 4212809.json: Too many open files
tee: 4214003.json: Too many open files
tee: 4208302.json: Too many open files
tee: 4203501.json: Too many open files
....

有没有一种方法可以一次按顺序将输出重定向到一个文件(或一次 10 个、20 个文件),而无需尝试一次打开所有文件?

[编辑] 作为卡米尔·马乔罗夫斯基正如我所写的那样,正确地指出,它不是pass_cd_to_std_out.py作为 的参数一一传递的输出tee,而是一次扩展并作为多个参数传递。

我将脚本重写为 for 循环:

#!/bin/bash

output_dir=Data

for url in $(eval python pass_urls_to_std_out.py); do
        curl -k $url > $output_dir/$(python pass_cd_to_std_out.py)
done

不幸的是,$output_dir仅评估一次,因此输出如下:

Data/1200401.json
4205407.json
4106902.json
2304400.json
3304557.json
3205309.json
1600303.json
1400100.json

答案1

我发现,如果不是即时管道传输所有内容,而是将每个步骤保存到文件中,它会以某种方式起作用:

  1. 检查目录是否Data存在,否则创建目录Data
    download_dir=Data
    
    if [ ! -d $download_dir ]; then
      mkdir $download_dir
    fi
    
  2. 创建一个包含所有 URL 的文件:
    python pass_urls_to_std_out.py >> urls.txt
    
  3. 创建一个包含所有文件名的文件:
    python pass_cd_to_std_out.py >> file_names.txt
    
  4. 逐行读取每个文件并从 url 递归下载数据并保存到文件名:
    paste urls.txt file_names.txt | while IFS= read -r url file_name; 
      do curl -k --output-dir=Data $url > $file_name; 
    done
    

我添加了该--output-dir选项,感谢拘萨罗南达 建议以及。

相关内容