작업은 간단합니다. 내 스크립트의 일부는 md5 및 sha1 해시를 계산해야 합니다. 입력은 파일(대형 파일)이며 나중에 출력 조합을 위해 해시를 MD 및 SH 변수에 넣어야 합니다.
처리되는 파일은 매우 크지만(수백 GB) 여러 번 읽고 사용하는 일종의 데이터를 사용하려고 합니다. 나는 프로세스 대체라는 것을 발견하고 다음과 같은 방식으로 채택했습니다.
$ dd if=big.tgz 2>/dev/null |tee >(sha1sum ) > >(md5sum ) ;
바꾸다:
$ SH=$(sha1sum big.tgz); MD=$(md5sum big.tgz);
그러나 나는 다음을 발견했습니다.
두 가지 모두 대략적인 시간이 필요하므로 리소스와 시간이 절약되지 않습니다. 40초(4.776GB 파일의 경우)
>(md5sum )
나중에 스크립트에서 사용하기 위해 하위 프로세스의 결과를 변수 MD에 저장하는 방법을 모르겠습니다.
나는 Pipelineexec를 이해하려고 노력하고 있지만 멋지고 다채로운 일러스트레이션이 있어도 성공하지 못했습니다.
VAR=$(command) 외에 출력을 변수로 리디렉션하는 다른 방법이 있습니까?
답변1
성능면에서는 CPU에 의해 제한될 수 있습니다. 실제로 MD5와 sha1sum은 40초 만에 4.7TB를 전송해 빠르게 느껴집니다. 그러니까 이렇게 일을 해도. 디스크 IO가 줄어들 것이라는 점은 언급할 가치가 있습니다.
실제로는 이렇게 할 필요가 없습니다 dd
. 나중에 사용하기 위해 sha1sum 및 md5sum의 출력을 파일에 직접 쓸 수도 있습니다.
tee < big.tgz >(sha1sum > big.tgz.sha1 ) > >(md5sum > big.tgz.md5 )
sha1=`cat big.tgz.sha1`
md5=`cat big.tgz.md5`
제가 아는 한 두 개의 변수를 동시에 다른 값으로 설정할 수 있는 방법이 없기 때문에 이와 같은 임시 파일( big.tgz.sha1
및 )을 사용하는 것이 좋습니다. big.tgz.md5
둘 중 하나를 변수에 직접 캡처할 수 있지만 둘 다 캡처할 수는 없습니다. 동일한 표준 출력을 허용 md5sum
하고 동시에 기록하면 예측할 수 없는 문제가 발생할 수 있습니다.sha1sum
답변2
음, 내부에 또 다른 리디렉션을 추가할 수 있습니다.
tee < big.tgz >(sha1sum > big.tgz.sha1sum) >(md5sum > big.tgz.md5sum)
sha1과 md5를 쉽게 구별할 수 있으므로 출력을 있는 그대로 얻을 수도 있습니다(길이가 다르기 때문에 어느 것이 어느 것인지 혼동할 필요가 없습니다).
를 사용하지 않고 자체적으로 여러 체크섬을 계산할 수 있는 유틸리티도 있습니다 tee
.
사실 위의 내용은 작성할 필요가 없습니다 tee
.
sha1sum big.tgz > big.tgz.sha1sum &
md5sum big.tgz > big.tgz.md5sum
wait # for sha1sum
이론적으로 이는 디스크에서 데이터를 두 번 읽으므로 좋지 않습니다.
실제로 두 판독기를 병렬로(및 백그라운드에서) 실행하면 디스크 캐시가 이를 처리하여 데이터가 실제로 한 번만 읽힐 수 있도록 해야 합니다. 이는 해싱이 빠르고 I/O가 느리기 때문에 어떤 프로세스도 다른 프로세스에서 벗어날 수 없다고 가정합니다.
(저는 이전에 다른 맥락에서 두 번 읽는 것에 대해 게시한 적이 있습니다.md5sum과 함께 pv 사용- 일반적으로 효과가 있지만 약간의 위험이 있으므로 tee
여전히 더 안정적인 방법입니다. )
답변3
parset
GNU Parallel은 변수를 병렬로 설정하고 --tee
여러 명령에 입력을 보내는 데 사용됩니다.
parset md5,sha1,sha256 --pipe --tee {} ::: md5sum sha1sum sha256sum < bigfile
echo $sha1
parset sumarr --pipe --tee {} ::: md5sum sha1sum sha256sum < bigfile
echo ${sumarr[1]}