md5sum 명령이 완료될 때까지 기다립니다.

md5sum 명령이 완료될 때까지 기다립니다.
#!/bin/bash

cd /path-to-directory
md5=$(find . -type f -exec md5sum {} \; | sort -k 2 | md5sum)

zenity --info \
--title= "Calculated checksum" \
--text= "$md5"

디렉터리에 대한 재귀 체크섬 계산 프로세스에는 시간이 걸립니다. Bash 스크립트는 프로세스가 완료될 때까지 기다리지 않고 단지 계산된 체크섬을 표시하는 대화 상자인 다음 명령으로 이동합니다. 따라서 대화 상자에 잘못된 체크섬이 표시됩니다.

체크섬 계산이 완료될 때까지 기다리도록 스크립트에 지시하는 옵션이 있습니까? 또한 체크섬 계산 진행 상황을 zenity와 같은 일종의 진행률 표시줄로 파이프하는 옵션이 있습니까?

답변1

쓰여진 대로 기다리겠습니다. 진동하는 진행률 표시줄의 경우:

#! /bin/sh -
export LC_ALL=C
cd /path/to/dir || exit
{
  md5=$(
    find . -type f -print0 |
      sort -z |
      xargs -r0 md5sum |
      md5sum
  )
  exec >&-
  zenity --info \
         --title="Checksum" \
         --text="$md5"
} | zenity --progress \
           --auto-close \
           --auto-kill \
           --pulsate \
           --title="${0##*/}" \
           --text="Computing checksum"

실제 진행률 표시줄을 위해서는 처리할 파일 수를 미리 알아야 합니다.

그리고 zsh:

#! /bin/zsh -
export LC_ALL=C
autoload zargs
cd /path/to/dir || exit
{
  files=(.//**/*(ND.))
} > >(
  zenity --progress \
         --auto-close \
         --auto-kill \
         --pulsate \
         --title=$0:t \
         --text="Finding files"
)
md5=(
  $(
   zargs $files -- md5sum \
      > >(
        awk -v total=$#files '/\/\// {print ++n * 100 / total}' | {
          zenity --progress \
            --auto-close \
            --title=$0:t \
            --text="Computing checksum" || kill -s PIPE $$
        }) \
      | md5sum
  )
)
zenity --info \
       --title=$0:t \
       --text="MD5 sum: $md5[1]"

로케일 외부에서는 C, 적어도 GNU 시스템에서는 파일 이름 순서가 정의되지 않습니다. 왜냐하면 일부 문자는 동일하게 정렬되며 위에서 설명한 대로 파일 이름이 유효한 텍스트로 구성된다는 보장이 없기 때문입니다 LC_ALL=C.

C 로케일 순서도 매우 간단하며(바이트 값 기준) 시스템과 버전 전반에 걸쳐 일관됩니다.

이는 오류 메시지(있는 경우)가 사용자의 언어가 아닌 영어로 표시된다는 것을 의미합니다(그러나 등도 현지화 Computing checksum되지 않았 Finding files으므로 괜찮습니다).

접근 방식에 대한 몇 가지 다른 개선 사항은 다음과 같습니다.

  • 각각 여러 파일을 전달하는 호출 수를 최소화하려면 -exec md5sum {} +또는 -print0 | xargs -r0 md5sum(또는 이와 동등한 것)을 사용하십시오 . 이는 각 파일에 대해 하나씩 실행하는 것을 의미하며 이는 매우 비효율적입니다.zargsmd5summd5sum-exec md5sum {} \;md5sum
  • 파일 목록을 에 전달하기 전에 정렬합니다 md5sum. 일반적으로 sort -k2파일 이름에 개행 문자가 포함될 수 있으므로 이 방법은 작동하지 않습니다. 일반적으로 파일 경로를 라인 단위로 처리하는 것은 잘못된 것입니다. 파일 수를 안정적으로 계산할 .//수 있도록 zsh 메서드에서 접두사를 사용한다는 것을 알 수 있습니다 awk. 일부 구현에서는 NUL로 구분된 레코드 옵션 md5sum도 제공합니다 .-z

답변2

이 코드는 대기 find하고 md5sum명령이 완료됩니다. &백그라운드로 명령을 보내야 하는 경우가 아니면 이는 정상적인 동작입니다 .

그러나 귀하의 zenity 명령 형식이 잘못되었습니다 =. 따라서 빈 zenity 창이 표시되는 것 같습니다. 이것이 바로 기다리지 않는다고 생각하는 이유입니다. 다시 시도하되 공백을 제거하십시오.

#!/bin/bash

cd /path-to-directory
md5=$(find . -type f -exec md5sum {} \; | sort -k 2 | md5sum)

zenity --info \
--title="Calculated checksum" \
--text="$md5"

이렇게 하면 필요성을 피하고 cd더 간결하게 만들 수도 있습니다.

#!/bin/bash

zenity --info \
--title="Calculated checksum" \
--text="$(find /path-to-directory -type f -exec md5sum {} \; | sort -k 2 | md5sum)"

디렉터리의 상위 경로가 무엇이든 항상 동일한 결과를 반환해야 하는 경우 이를 사용하여 find ... md5sum두 번째 경로에 전달하기 전에 명령 출력에서 ​​파일 이름을 제거할 수 있습니다 md5sum.

#!/bin/bash

zenity --info \
--title="Calculated checksum" \
--text="$(find /path-to-directory -type f -exec md5sum {} \; | cut -d ' ' -f1 | sort -k 2 | md5sum)"

관련 정보