結局、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
パッケージの.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)スクリプトもバグである可能性があります。それらを修正する必要がある場合もあります。
彼らがそれを修正できるように、パッケージを作った人にバグレポートを提出することを忘れないでください。
パッケージ化されたソフトウェアには、失敗する「インストール前スクリプト」(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
ファイルを抽出し、preinst
スクリプトがコード1
で終了する理由を確認する必要があります。
これを行う方法に関連してUNIX.SEに関する議論があったかどうかはわかりませんが、AskUbuntuの この質問 を見て、抽出方法のアイデアを得ることができます。
この後、手動でpreinst
スクリプトを実行して、パッケージのインストールが失敗した理由を確認する必要があります。
パッケージを直接編集したい場合は、これを試してください:
#!/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"