작업은 간단합니다. 내 스크립트의 일부는 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에 저장하는 방법을 모르겠습니다.
나는 Pipexec을 이해하려고 노력했지만 멋진 컬러 일러스트레이션도 아직까지는 성공하지 못했습니다.
VAR=$(command) 이외의 출력을 vriable로 리디렉션하는 다른 방법이 있습니까?
답변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`
AFAIK에는 두 변수를 서로 다른 값으로 동시에 설정할 수 있는 방법이 없기 때문에 이와 같은 임시 파일( big.tgz.sha1
및 ) 을 사용하는 것이 좋습니다. big.tgz.md5
하나를 변수로 직접 캡처할 수 있지만 둘 다를 캡처할 수는 없습니다. 그리고 동시에 동일한 stdout에 쓰기 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]}