나는 결국 dpkg를 사용하여 배포할 소프트웨어 작업을 하게 되었습니다. .deb 패키지는 테스트 환경에서는 잘 작동하지만 준비할 때는 실패합니다. 둘 다 동일한 버전의 Ubuntu를 실행하고 있지만 나머지 구성에 대해서는 100% 확신할 수 없습니다. 이 dpkg 문제를 추가로 디버깅하려면 어떻게 해야 합니까?
다음과 같이 설치가 실패했습니다.
sudo dpkg -i --debug=7337 package.deb
D000010: ensure_pathname_nonexisting `/var/lib/dpkg/tmp.ci'
(Reading database ... 201812 files and directories currently installed.)
Unpacking myProprietarySoftware (from package.deb) ...
D000001: process_archive oldversionstatus=not installed
D000002: fork/exec /var/lib/dpkg/tmp.ci/preinst ( install )
dpkg: error processing package.deb (--install):
subprocess new pre-installation script returned error exit status 1
D000002: maintainer_script_new nonexistent postrm `/var/lib/dpkg/tmp.ci/postrm'
D000010: ensure_pathname_nonexisting `/var/lib/dpkg/tmp.ci'
D000010: ensure_pathname_nonexisting running rm -rf
D000010: ensure_pathname_nonexisting `/var/lib/dpkg/reassemble.deb'
Errors were encountered while processing:
package.deb
답변1
어떤 이유로 패키지의 .preinst 스크립트가 실패했습니다.
이유를 알아 보려면 다음 스크립트를 확인하십시오./var/lib/dpkg/info/PACKAGENAME.preinst
스크립트가 실패한 줄을 정확히 확인하려면 .preinst 스크립트를 편집하고 해당 줄 set -x
바로 뒤에 추가하세요 . #!
그러면 스크립트에서 실행 추적이 활성화됩니다.
노트:이는 .preinst 스크립트가 쉘 스크립트(posix sh 또는 bash)라고 가정합니다. 거의 모든.preinst(및 .postinst, .prerm 및 .postrm) 스크립트는 쉘 스크립트이지만 실행 파일일 필요는 없습니다. 예를 들어, 9104개의 패키지가 설치된 기본 데스크톱 컴퓨터에서 14개는 Perl 스크립트이고 1개는 컴파일된 실행 파일(bash의 preinst - 작동하는 쉘이 설치되어 있다고 가정할 수 없음)이고 나머지는 모두 쉘 스크립트입니다... 9041은 POSIX 쉘 스크립트이고 63은 bash 스크립트입니다. .preinst가 Perl이나 Python 등인 경우 해당 언어에서 디버깅이나 실행 추적 모드 또는 유사한 모드를 활성화하는 방법을 알아내야 합니다.
그런 다음 dpkg --configure --pending
.
이로 인해 dpkg는 절반만 설치된 패키지를 구성하려고 시도합니다. 다시 설치하지 마십시오 dpkg -i
. 그러면 편집한 .preinst 스크립트를 .deb 패키지의 버전으로 덮어쓰게 됩니다.
이를 통해 문제를 해결하는 데 충분한 정보를 얻을 수 있습니다. 이는 프로그램의 예기치 않거나 포착되지 않은 종료 코드(대부분의 .preinst 등 스크립트에 포함되어 있어 set -e
첫 번째 오류 시 종료되도록 함)처럼 간단하거나 디렉토리가 이미 존재한다고 가정하는 것일 수 있습니다(선언되지 않았기 때문일 수 있음). 종속성)을 패키지의 debian/control 파일에 포함합니다. 즉, foo에 의존해야 하지만 어쨌든 foo는 설치되지 않습니다.
복구 후 dpkg --configure --pending
다시 실행하면 패키지가 올바르게 설치됩니다.
.preinst 스크립트에 오류가 있으면 .postinst(및/또는 .prerm 및 .postrm) 스크립트에도 오류가 있을 수 있습니다. 문제를 해결해야 할 수도 있습니다.
패키지 작성자가 수정할 수 있도록 버그 보고서를 제출하는 것을 잊지 마세요.
답변2
패키지된 소프트웨어에는 실패한 "preinst"가 포함되어 있습니다. 이는 .deb 파일에 포함된 쉘 스크립트입니다. 다음을 사용하여 추출할 수 있습니다.
dpkg-deb -e some-deb.deb out-dir
그런 다음 이를 살펴 out-dir/preinst
보고 실패한 이유를 알아낼 수 있는지 확인할 수 있습니다.
스크립트를 수정하고 다시 빌드하려면 .deb
(디버깅 코드를 추가할 수도 있음) 다음을 시도해 보세요.
dpkg-deb -x some-deb.deb another-out-dir
dpkg-deb -e some-deb.deb another-out-dir/DEBIAN
(modify another-out-dir/DEBIAN/preinst)
dpkg-deb -b another-out-dir some-deb2.deb
답변3
파일의 압축을 풀고 preinst
스크립트가 code 와 함께 종료되는 이유를 확인해야 합니다 1
.
이 작업을 수행하는 방법과 관련된 UNIX.SE에 대한 토론이 있는지 확실하지 않지만 살펴볼 수 있습니다.이 문제AskUbuntu에서 추출하는 방법을 알아보세요.
그런 다음 preinst
스크립트를 수동으로 실행하여 패키지 설치가 실패한 이유를 확인해야 합니다.
답변4
패키지를 직접 편집하려면 다음을 시도하십시오.
#!/bin/bash
if [[ -z "$1" ]]; then
echo "Syntax: $0 debfile"
exit 1
fi
DEBFILE="$1"
TMPDIR=`mktemp -d /tmp/deb.XXXXXXXXXX` || exit 1
OUTPUT=`basename "$DEBFILE" .deb`.modfied.deb
if [[ -e "$OUTPUT" ]]; then
echo "$OUTPUT exists."
rm -r "$TMPDIR"
exit 1
fi
dpkg-deb -x "$DEBFILE" "$TMPDIR"
dpkg-deb --control "$DEBFILE" "$TMPDIR"/DEBIAN
if [[ ! -e "$TMPDIR"/DEBIAN/control ]]; then
echo DEBIAN/control not found.
rm -r "$TMPDIR"
exit 1
fi
CONTROL="$TMPDIR"/DEBIAN/control
MOD=`stat -c "%y" "$CONTROL"`
vi "$CONTROL"
if [[ "$MOD" == `stat -c "%y" "$CONTROL"` ]]; then
echo Not modfied.
else
echo Building new deb...
dpkg -b "$TMPDIR" "$OUTPUT"
fi
rm -r "$TMPDIR"