![출력을 여러 파일로 리디렉션하려고 할 때 "tee: 너무 많은 열린 파일"을 수정하는 방법](https://linux55.com/image/213981/%EC%B6%9C%EB%A0%A5%EC%9D%84%20%EC%97%AC%EB%9F%AC%20%ED%8C%8C%EC%9D%BC%EB%A1%9C%20%EB%A6%AC%EB%94%94%EB%A0%89%EC%85%98%ED%95%98%EB%A0%A4%EA%B3%A0%20%ED%95%A0%20%EB%95%8C%20%22tee%3A%20%EB%84%88%EB%AC%B4%20%EB%A7%8E%EC%9D%80%20%EC%97%B4%EB%A6%B0%20%ED%8C%8C%EC%9D%BC%22%EC%9D%84%20%EC%88%98%EC%A0%95%ED%95%98%EB%8A%94%20%EB%B0%A9%EB%B2%95.png)
json
URL 에 저장된 파일에서 URL을 다운로드 해야 합니다 csv
. 이 작업을 수동으로 수행할 수 없기 때문에 Python을 사용하여 URL을 하나씩 읽고 curl
다운로드에 전달하는 짧은 bash 스크립트를 작성했습니다. 또한 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
URL을 읽고 하나씩 표준 출력으로 전달하는 짧은 Python 스크립트입니다.
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
모든 것을 즉시 파이핑하는 대신 각 단계를 파일에 저장하면 어떻게든 작동한다는 것을 알았습니다.
- 디렉터리가
Data
있는지 확인하고, 그렇지 않으면 디렉터리를 만듭니다Data
.download_dir=Data if [ ! -d $download_dir ]; then mkdir $download_dir fi
- 모든 URL을 포함하는 파일을 만듭니다.
python pass_urls_to_std_out.py >> urls.txt
- 모든 파일 이름을 포함하는 파일을 만듭니다.
python pass_cd_to_std_out.py >> file_names.txt
- 각 파일을 한 줄씩 읽고 URL에서 데이터를 재귀적으로 다운로드하여 파일 이름에 저장합니다.
paste urls.txt file_names.txt | while IFS= read -r url file_name; do curl -k --output-dir=Data $url > $file_name; done