저는 임베디드 Linux 시스템(커널 v3.10.31)에서 BusyBox 1.24.1을 사용하고 있는데 파일의 압축을 풀 때 이해할 수 없는 동작이 발생합니다. "알려진 양호한" 파일(예: 동일한 시스템에서 명령으로 방금 생성한 파일) 이 제공되는 경우에도 명령 gunzip
이 출력되지 않고(항상 그런 것은 아님) 실패합니다(오류 메시지도 표시되지 않음) . 실제로 압축을 풀 수 있는 파일을 찾기가 어렵습니다. "유레카!"를 느낀 사람이 있나요? 이거 보면서?.gz
gzip
텍스트 파일의 어떤 것으로 인해 gunzip
명령이 실패하는 것 같지만 무엇인지 모르겠습니다. 아래를 참조하세요:
# ls -l
-rw------- 1 root root 65 Sep 13 10:02 cantunzip
-rw------- 1 root root 64 Sep 13 10:01 canunzip
more cantunzip
fsdgafjklsdfasdsdjfhjafasdohfkl asdfas a fsd a
2132313 12 51515
# more canunzip
fsdgafjklsdfasdsdjfhjafasdohfkl asdfas a fsd a
2132313 12 51515
# hexdump cantunzip
0000000 7366 6764 6661 6b6a 736c 6664 7361 7364
0000010 6a64 6866 616a 6166 6473 686f 6b66 206c
0000020 7361 6664 7361 6120 6620 6473 6120 0a0a
0000030 3132 3233 3133 2033 3231 3520 3531 3531
0000040 000a
0000041
# hexdump canunzip
0000000 7366 6764 6661 6b6a 736c 6664 7361 7364
0000010 6a64 6866 616a 6166 6473 686f 6b66 206c
0000020 7361 6664 7361 6120 6620 6473 6120 320a
0000030 3331 3332 3331 3120 2032 3135 3135 0a35
0000040
# gzip canunzip
# gzip cantunzip
# ls -l
-rw------- 1 root root 77 Sep 13 10:04 cantunzip.gz
-rw------- 1 root root 77 Sep 13 10:03 canunzip.gz
# gunzip canunzip.gz
# echo $?
0
# gunzip cantunzip.gz
# echo $?
1
# ls -l
-rw------- 1 root root 77 Sep 13 10:04 cantunzip.gz
-rw------- 1 root root 64 Sep 13 10:04 canunzip
답변1
gunzip 명령으로 압축해제 실패에 대한 오류 코드를 확인할 수 있습니다.
echo $?
이를 통해 실패에 대한 단서를 얻을 수 있습니다.
두 파일의 16진수 덤프를 가져와 비교하는 것도 도움이 될 수 있습니다.
답변2
그만한 가치가 있는 만큼,비지박스 뉴스이 페이지에는 1.28.0을 제외한 1.24.0과 1.32.0 사이의 모든 마이너 버전의 gzip 애플릿 업데이트가 나열되어 있으므로 busybox 1.35.0을 사용하는 Debian 시스템에서 이를 재현할 수 있을지 확신할 수 없습니다. 현재 안정 버전은 1.34.1입니다.가장 좋은 방법은 업그레이드하는 것입니다.
업그레이드가 옵션이 아닌 경우, 이 쉘 래퍼 기능은 최소한 명령에 어느 정도 온전한 상태를 제공해야 합니다.
gzip() {
local target
for target in "$@"; do true; done
cp -p "$target" "$target.temp" || return $?
busybox gzip "[email protected]"
gunzip < "$target.temp.gz" > "$target.temp"
if [ $? = 0 ] && diff -q "$target" "$target.temp" >/dev/null 2>&1; then
rm -f "$target" "$target.temp"
mv "$target.temp.gz" "$target.gz"
return 0
fi
echo "gzip: failure" >&2
rm -f "$target.temp.gz" "$target.temp"
return 1
}
이를 파일(예: ~/.bashrc
)에 넣고 가져오면(예: source ~/.bashrc
) 정상적으로 gzip을 사용할 수 있습니다. 이 함수는 마지막 매개변수가 압축할 대상 파일이라고 가정 하고 명령 매개변수를 반복 하여 마지막 매개변수만 $target
. 사본에 모든 매개변수가 포함된 busybox 애플릿. 남은 것은 리뷰와 하우스키핑뿐입니다.gzip -k
gzip
파일을 확인하려면 파이프를 사용하여 압축을 풀어 .gz 버전을 보존한 다음 성공( $?
이전 명령의 종료 코드이며 실행 시 0이었음)과 원본 파일과 다른 파일이 아닌지 확인하면 됩니다. 표적. 이 경우 .gz가 검증되었으므로 테스트 파일과 원본 파일은 삭제되고 성공값이 반환된다 0
. 그렇지 않으면 표준 오류에 대한 실패를 선언하고 테스트 파일과 문제가 있는 .gz 파일(있는 경우)을 삭제하고 오류 값을 반환합니다 1
.
스크립트로 만들 수도 있습니다. 처음 두 줄과 마지막 줄을 삭제하고 새로운 첫 번째 줄을 추가한 다음 파일을 실행 가능 #!/bin/sh
하게 만들고 .$PATH
gzip