md5sum
다음을 사용 하여 pv
동일한 디렉토리에 있는 4GiB 파일을 확인했습니다 .
md5sum dir/* | pv -s 4g | sort
명령은 약 28초 안에 성공적으로 완료되지만 pv
모든 오류가 출력됩니다. 다음은 전체에 표시된 출력 유형입니다.
219 B 0:00:07 [ 125 B/s ] [> ] 0% ETA 1668:01:09:02
-s 4g
및 없이도 마찬가지입니다 | sort
. 저도 다른 파일로 시도해 봤습니다.
pv
with를 사용해 보았는데 cat
출력이 잘 나오네요. md5sum
.
답변1
이 pv
유틸리티는 "이국적 cat
"입니다. 즉, pv
사용해야 하는 대부분의 상황에서 사용할 수 있다는 의미입니다 cat
.
cat
with 를 사용하면 md5sum
단일 파일의 MD5 체크섬을 계산할 수 있습니다.
cat file | md5sum
또는 pv
,
pv file | md5sum
md5sum
그러나 불행하게도 이 방법 으로는 파일 이름이 출력에 올바르게 삽입되는 것을 허용하지 않습니다 .
이제 운 pv
좋게도진짜fancy cat
, 일부 시스템(Linux)에서는 가능합니다.보다데이터가 다른 프로세스를 통해 전달되고 있습니다. 이는 -d
다른 프로세스의 프로세스 ID와 함께 해당 옵션을 사용하여 수행됩니다.
이는 다음과 같은 작업을 수행할 수 있음을 의미합니다.
md5sum dir/* | sort >sums &
sleep 1
pv -d "$(pgrep -n md5sum)"
이렇게 하면 프로세스 pv
를 볼 수 있습니다 md5sum
. 이는 백그라운드에서 실행 중인 프로그램이 올바르게 시작될 수 sleep
있도록 하기 위한 것 입니다. md5sum
당신이 소유한 pgrep -n md5sum
가장 최근에 시작된 프로세스의 PID를 반환합니다. 모니터링 중인 프로세스가 종료되자마자 종료됩니다.md5sum
pv
pv
이 특정 실행 방법을 몇 번 테스트해 본 결과 일반적으로 잘 작동하는 것 같았지만 때로는 md5sum
다음 파일로 전환하면서 아무것도 출력하지 않는 것 같습니다. 때로는 셸에서 가짜 백그라운드 작업을 생성하는 것처럼 보입니다.
달리는 것이 가장 안전할 것 같아요
md5sum dir/* >sums &
sleep 1
pv -W -d "$!"
sort -o sums sums
이 -W
옵션을 사용하면 실제 데이터가 전송될 때까지 기다리게 되지만 pv
항상 안정적으로 작동하는 것은 아닙니다.
답변2
파이프를 통해 제공하는 데이터는 md5sum
처리 중인 파일의 데이터 가 아니라 md5sum
각 파일에 대해 한 줄(MD5 해시, 공백 두 개, 파일 이름)로 구성된 출력입니다. 우리는 이를 미리 알고 있으므로 pv
그에 따라 알림을 보내 정확한 진행률 표시기를 표시할 수 있습니다. 이를 수행하는 방법에는 두 가지가 있습니다.
첫 번째로 선호되는 방법(Frosschutz가 제안)은 처리된 각 파일이 한 줄을 생성한다는 사실과 바이트 대신 줄을 계산하는 줄 모드가 있다는 사실을 활용합니다 md5sum
. pv
이 모드에서 pv
진행률 표시줄은 처리량에서 개행 문자가 발견될 때만 이동됩니다(즉, 각 파일이 에 의해 완료됨) md5sum
. Bash에서 첫 번째 방법은 다음과 같습니다.
set -- *.iso; md5sum "$@" | pv --line-mode -s $# | sort
set
처리할 파일의 위치 매개변수를 설정하는 기능 내장 ( *.iso
쉘로 확장된 쉘 모드) md5sum
그런 다음 이러한 파일은 처리되도록 지시되며( $@
위치 인수로 확장), pv
라인 모드에서는 라인이 파일로 처리/출력될 때마다 진행 표시기가 이동됩니다 md5sum
. 특수 쉘 인수는 위치 인수 수로 확장되므로 pv
예상할 수 있는 총 행 수( )를 알고 있다는 점은 주목할 가치가 있습니다.-s $#
$#
두 번째 방법은 행 기반이 아니라 바이트 기반입니다. 이는 md5sum
불필요하게 복잡하지만 일부 다른 프로그램에서는 행을 생성하지 않지만 연속 데이터를 생성할 수 있으므로 이 접근 방식이 더 실용적일 수 있습니다. 나는 md5sum
그것을 설명합니다. 아이디어는 md5sum
(또는 다른 프로그램)이 이를 알리기 위해 생성하고 사용할 데이터의 양을 계산하는 것입니다 pv
. Bash에서는 다음과 같이 보일 수 있습니다:
os=$(( $( ls -1 | wc -c ) + $( ls -1 | wc -l ) * 34 ))
md5sum * | pv -s $os | sort
첫 번째 줄은 출력 크기( os
) 추정치를 계산합니다. 첫 번째 항목은 파일 이름(줄 바꿈 포함)을 인코딩하는 데 필요한 바이트 수이고, 두 번째 항목은 MD5 해시(각각 32자)를 인코딩하는 데 사용되는 바이트 수입니다. , 공백 2개를 추가하세요. 두 번째 줄에서는 최대 100% 정확한 진행률 표시기(완성된 md5summed 파일을 기반으로 업데이트됨)를 표시할 수 있도록 pv
예상 데이터 양을 바이트 단위로 알려줍니다 .os
분명히 이 두 가지 방법은 처리할 파일이 여러 개 있는 경우에만 실용적입니다. 또한 의 출력은 프로그램이 기본 데이터를 처리하는 데 소요 md5sum
되는 시간과 상관 관계가 없으므로 md5sum
진행률 표시기가 다소 오해의 소지가 있는 것으로 간주될 수 있습니다. 예를 들어, 두 번째 접근 방식에서는 이름이 가장 짧은 파일이 실제로는 가장 크더라도 가장 낮은 진행률 업데이트를 생성합니다. 그런 다음 모든 파일의 크기와 이름이 비슷한 경우에는 문제가 되지 않습니다.
답변3
각 파일의 진행 상황을 확인하는 더러운 방법은 다음과 같습니다.
for f in iso/*
do
pv "$f" | (
cat > /dev/null &
md5sum "$f"
wait
)
done
모습:
4.15GiB 0:00:32 [ 130MiB/s] [================================>] 100%
0db0b36fc7bad7b50835f68c369e854c iso/KNOPPIX_V7.6.1DVD-2016-01-16-EN.iso
792MiB 0:00:06 [ 130MiB/s] [================================>] 100%
97537db63e61d20a5cb71d29145b2937 iso/archlinux-2016.10.01-dual.iso
843MiB 0:00:06 [ 129MiB/s] [================================>] 100%
1b5dc31e038499b8409f7d4d720e3eba iso/lubuntu-16.04-desktop-i386.iso
259MiB 0:00:02 [ 130MiB/s] [=========> ] 30% ETA 0:00:04
...
이제 이것은 몇 가지 가정을 합니다. 첫째, 데이터를 읽는 것이 데이터를 해싱하는 것보다 느립니다. 둘째, OS는 I/O를 캐시하므로 완전히 독립적인 판독기라도 데이터가 pv
(물리적으로) 두 번 읽히지 않습니다 md5sum
.
이 더러운 해킹의 좋은 점은 하나의 파일이 아닌 모든 데이터에 대한 진행률 표시줄을 만들기 위해 쉽게 조정할 수 있다는 것입니다. 그리고 사실 이후에 출력을 정렬하는 것과 같은 이상한 작업을 계속 수행합니다.
pv iso/* | (
cat > /dev/null &
md5sum iso/* | sort
wait
)
모습(진행 중):
15.0GiB 0:01:47 [ 131MiB/s] [===========================> ] 83% ETA 0:00:21
모습(완료):
18.0GiB 0:02:11 [ 140MiB/s] [================================>] 100%
0db0b36fc7bad7b50835f68c369e854c iso/KNOPPIX_V7.6.1DVD-2016-01-16-EN.iso
155603390e65f2a8341328be3cb63875 iso/systemrescuecd-x86-4.2.0.iso
1b5dc31e038499b8409f7d4d720e3eba iso/lubuntu-16.04-desktop-i386.iso
1b6ed6ff8d399f53adadfafb20fb0d71 iso/systemrescuecd-x86-4.4.1.iso
25715326d7096c50f7ea126ac20eabfd iso/openSUSE-13.2-KDE-Live-i686.iso
...
이제 이것은 해커를 위한 것입니다. 올바른 해결 방법은 다른 답변을 확인하세요. ;-)
답변4
의견 및 기타 답변에서 이미 지적했듯이:
- 출력(체크섬 및 파일 이름)
pv
만 파이핑하므로 진행률 표시줄에는 읽고 있는 데이터의 양이 표시되지 않습니다.md5sum
pv
md5sum
- 4GB는 확실히 너무 크네요. 또한
pv
가져올 파일의 크기를 제공(수동으로 사용-s
)하는 것도 불편합니다.
파일의 내용을 파이핑 pv
한 다음 다시 입력하면 md5sum
진행률 표시줄이 표시되지만 파일 이름은 손실됩니다.
이 코드는 의미 있는 진행률 표시줄과 체크섬이 있는 파일 이름을 모두 갖는 우아한 방법이 아닙니다.
#!/bin/sh
for file in "$@"; do
pv -- "$file" |
md5sum |
sed 's/-$//' |
printf '%s%s\n' "$(cat -)" "$file"
done
스크립트는 다음과 같이 호출됩니다.
./script dir/*
물론 호출하기 위해 경로를 입력할 필요가 없도록(또는 경로를 추가할 필요 없이 함수로 선언할 수 있습니다 PATH
):
function pvsum () {
for file in "$@"; do
pv -- "$file" |
md5sum |
sed 's/-$//' |
printf '%s%s\n' "$(cat -)" "$file"
done
}
이렇게 하면 명령 pvsum dir/* | sort
이 md5sum dir/* | pv -s <size> | sort
.
출력:
$ ./testscript testdir/*
4.00GiB 0:00:09 [ 446MiB/s] [==============================>] 100%
9dab5f8add1f699bca108f99e5fa5342 testdir/file1
1.00GiB 0:00:02 [ 447MiB/s] [==============================>] 100%
06a738a71e3fd3119922bdac259fe29a testdir/file2
할 수 있는 작업:
- 주어진 파일과 각 파일을 반복합니다.
pv
파일을 에 파이프하여md5sum
기본 진행률 표시줄을 표시합니다.sed
-
인쇄를 제거하기 위해md5sum
(stdin에서 읽기) 출력을 소비에 적합하게 만들려고 시도합니다md5sum -c
(감사합니다)프로스트슈츠이것을 지적하라) 1 .- 파일 이름 뒤에 체크섬을 표준 출력으로 인쇄합니다.
에 대한 sort
:
예상되는 결과가 무엇인지 잘 모르므로 무시했습니다. pv
진행률 표시줄이 표준 오류에 기록되므로 모든 것을 파이핑하면 의 sort
출력과 의 출력이 분리됩니다. 어쨌든 위의 코드를 추가하고 결과가 제대로 작동하는지 확인할 수 있습니다.pv
md5sum
| sort
done
1md5sum -c
파일 이름에 개행 문자가 포함되어 있으면 위에 표시된 코드의 출력이 맞지 않습니다. 줄 바꿈을 처리하는 것이 가능하지만 일부 버전은 md5sum
이와 관련하여 다르게 동작합니다(예를 들어 답변 참조).이 문제), 일반적인 솔루션을 공식화하는 것은 쉽지 않습니다(그리고 이 답변의 범위를 벗어납니다).
최신 버전을 사용하고 있다고 가정하면 md5sum
이 문제를 해결하기 위한 시도는 다음과 같습니다.
for file in "$@"; do
pv -- "$file" |
md5sum |
sed 's/-$//' |
printf '%s%s\n' "$(cat -)" "$file" |
sed -n 'H; 1h; $!d; g; s/\\/\\\\/g; s/\n/\\n/g; t x; p; q; :x s/^/\\/; p;'
done
유일한 추가 사항인 마지막 은 다음 sed
과 같습니다.
- 현재 파일의 전체 입력, 체크섬 및 이름을 패턴 공간에 넣습니다. 새 줄이 포함될 수 있기 때문입니다.
H
새 줄과 현재 패턴 공간을 예약된 공간에 추가하고 첫 번째 줄에 대해서만 이전을1h
덮어 씁니다.H
줄 바꿈은 추가되지 않습니다.$!d
현재 줄이 마지막 줄이 아니면 새 루프가 시작됩니다.g
예약된 공간의 내용이 패턴 공간에 배치됩니다. \
생성된 패턴 공간에서 백슬래시를 이스케이프하려면 백슬래시( )를 사용하십시오 .\n
결과 패턴 공간에서 줄 바꿈 으로 대체됩니다 .- 백슬래시가 체크섬의 시작 부분에 추가되어 적어도 하나의 백슬래시 또는 개행 문자가 대체된 경우(
t x
: 레이블로 분기 됨)에만 이스케이프를 취소해야 함 을 나타냅니다. 두 경우 모두 패턴 공간은 종료하기 전에 표준 출력으로 인쇄됩니다( )(이 옵션은 자동 인쇄를 비활성화합니다).x
md5sum -c
p
-n