md5sum과 함께 pv 사용

md5sum과 함께 pv 사용

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. 저도 다른 파일로 시도해 봤습니다.

pvwith를 사용해 보았는데 cat출력이 잘 나오네요. md5sum.

답변1

pv유틸리티는 "이국적 cat"입니다. 즉, pv사용해야 하는 대부분의 상황에서 사용할 수 있다는 의미입니다 cat.

catwith 를 사용하면 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를 반환합니다. 모니터링 중인 프로세스가 종료되자마자 종료됩니다.md5sumpv

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

의견 및 기타 답변에서 이미 지적했듯이:

  1. 출력(체크섬 및 파일 이름) pv만 파이핑하므로 진행률 표시줄에는 읽고 있는 데이터의 양이 표시되지 않습니다.md5sumpvmd5sum
  2. 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/* | sortmd5sum 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출력과 의 출력이 분리됩니다. 어쨌든 위의 코드를 추가하고 결과가 제대로 작동하는지 확인할 수 있습니다.pvmd5sum
| sortdone


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: 레이블로 분기 됨)에만 이스케이프를 취소해야 함 을 나타냅니다. 두 경우 모두 패턴 공간은 종료하기 전에 표준 출력으로 인쇄됩니다( )(이 옵션은 자동 인쇄를 비활성화합니다).xmd5sum -cp-n

관련 정보