파일을 사용하기 전에 삭제하고 싶기 때문에 이 예에서는 paste
시작하기 전에 col1, col2...col1000의 링크를 해제하고 싶습니다.
exec 3< col1 4< col2 ... 1002< col1000
rm col1 col2 ... col1000
paste /dev/fd/3 /dev/fd/4 ... /dev/fd/1002
이는 GNU/Linux+bash에서 잘 작동합니다. 그러나 /dev/fd/X
다른 시스템으로 이식할 수는 없습니다.
내가 사용할 수 있는 bash
명령 대체는 다음과 같습니다 .
exec 3< col1 4< col2 ... 1002< col1000
rm col1 col2 ... col1000
paste <(cat <&3) <(cat <&4) ... <(cat <&1002)
하지만 이렇게 하면 파일당 하나의 프로세스가 필요합니다.
모든 시스템에서 Bash와 작동하는 방식으로 위의 내용을 작성할 수 있습니까? 어쩌면 특별한 Bash 구문이 있을까요?
답변1
가장 간단한 이식 가능한 솔루션은 파일 설명자 번호를 인수로 사용하고 paste
파일 설명자 리디렉션이 포함된 내장 함수를 사용하여 이를 반복하는 함수로 바꾸는 것입니다.read
paste()
{
at_least_one_read_succeeded=true
while $at_least_one_read_succeeded
do
at_least_one_read_succeeded=false
first_fd=true
for fd in "$@"
do
if ! $first_fd
then
printf '\t'
fi
if IFS= read -r line <&"$fd"
then
at_least_one_read_succeeded=true
fi
printf '%s' "$line"
first_fd=false
done
printf '\n'
done
}
가장 큰 단점은 쉘의 내장 기능이 별도의 시스템 호출을 read
수행할 수밖에 없기 때문에 속도가 훨씬 느리다는 것입니다.read
각 바이트마다. 마찬가지로 printf
명령을 호출할 때마다 최소한 하나의 write
시스템 호출을 수행해야 합니다(이론적으로 누군가는 최적화 컴파일러와 JIT VM이 수행하는 것과 동일한 분석을 사용하여 이 경우 I/O를 최적화할 수 있는 셸을 작성할 수 있습니다). , 그러나 현재 그러한 쉘은 존재하지 않습니다). 대부분의 경우 최신 하드웨어에서는 그 차이가 여전히 무시할 수 있지만 예제에 수천 개의 파일이 포함되어 있으므로 실제로 성능 저하가 나타날 수 있으며 이는 사용 사례에서 중요합니다.
물론, 시간과 노력을 존중하는 것 외에는 쉘에서 자체적으로 버퍼링된 I/O를 롤링하는 것을 막을 수 있는 방법이 없습니다. 예를 들어, dd bs=4096 count=1
한 번에 4096바이트를 각 FD에 대한 별도의 변수로 읽은 다음 줄 바꿈이 부족할 때까지 해당 줄을 가져올 수 있습니다. 예 를 들어 , 라는 bash 배열을 만들고 buffers
다음을 buffers[$fd]=$(dd bs=4096 count=1 <$&fd)
사용하여 읽을 수 있습니다. ${buffers[$fd]%%'$\n'*}
솔직히 말해서, 이것을 고려하고 있고 col
이러한 파일을 디스크에 보관하지 않는 것이 매우 중요하다면 이러한 열 파일의 전체 내용을 변수로 읽는 것을 고려할 수도 있습니다 bash
. 데이터 크기는 모르겠습니다. 하지만 시스템이 bash
그 정도의 할당을 허용하고 bash
자체적으로 처리한다면진짜이러한 파일이 디스크에 남아 있지 않도록 방지하는 것도 중요하지만 콘텐츠가 지정된 파일에 전혀 닿지 않도록 하는 것도 충분히 중요할 수 있습니다.
하지만 한 발 뒤로 물러서면 이 정도면 충분하지 않을까요?
paste col1 col2 ... col1000 & # background `paste`
# optionally, put a tiny sleep here
rm col1 col2 ... col1000
wait # wait for `paste` to finish
col*
솔직하게 말해서 파일이 정리되지 않을 수 있는 시간이 항상 있기 때문입니다 ( rm
코드 또는 이전에 실행 중이던 코드에 rm
정전이 발생하면 어떻게 될까요 paste
?). 창이 부팅되고 시스템 호출을 통해 모든 매개변수에 도달할 paste
때 창이 <=1초 동안 지속된다면(최신 하드웨어에서는 1밀리초 미만이면 충분할 수 있음) 정말 더 나쁠까요 ?open
고려해야 할 또 다른 사항은 임시 파일 시스템을 사용하는 것입니다. 많은 운영 체제는 특정 경로에 메모리 내 파일 시스템을 제공합니다. 예를 들어, 거의 모든 Linux 배포판에는 일반적으로 각 사용자가 개인 디렉터리를 얻는 마운트 지점이 /run
있습니다 . 전원이 꺼지거나 상자를 재부팅하거나 종료하면 그 안의 모든 항목이 저장되지 않습니다. 실행해야 하는 다른 시스템이 무엇인지는 모르겠지만 해당 시스템에 임시 메모리 파일 시스템이 있는지 또는 재부팅 시 OS 디렉터리에 의해 지워지는 것이 보장되는지 확인하는 것이 좋습니다.tmpfs
/run/$(id -u)
tmpfs