以下のコードを貼り付けて保存し、実行権限を与えてください。ファイル名はdeb2sfs.shがお勧めですが、それ以外でも構いません。
コード: 全て選択
#!/usr/bin/env sh
## DebianパッケージをSquashFSに変換する
#
# @author ssnys
# @version 0.1.0
# @date 2018-06-22
# @licence https://creativecommons.org/licenses/by/4.0/
# @see http://sakurapup.com/forum1/viewtopic.php?f=31&t=3372
deb2sfs () (
# shの設定
set -eu
# gettextの設定
TEXTDOMAIN='deb2sfs.sh'; export TEXTDOMAIN
# プログラム名
name='deb2sfs.sh'
# バージョン
version='0.1.0'
# 最終更新日
update='2018-06-22'
# ヘルプメッセージ
helpMessage=`cat <<EOF
\`gettext 'Usage'\`: ${0} [options] dest [source1] [source2] ...
\`gettext 'Converrt Debian package to SquashFS.'\`
\`gettext 'Options'\`:
-c, --control \`gettext 'build Debian package control file'\`
-n, --no-sfs \`gettext 'do not make SquashFS'\`
-o name[:value], --option=name[:value] \`gettext 'option of mksquashfs command'\`
-h, --help \`gettext 'display this help and exit'\`
-v, --verbose \`gettext 'enable verbose output'\`
-V, --version \`gettext 'output version information and exit'\`
\`gettext 'Example'\`:
${0} output.sfs *.deb
${0} -cv output.sfs *.deb
${0} -o b:1048576 -o comp:xz -o Xdict-size:100% output.sfs *.deb
\`gettext 'See'\`: <http://sakurapup.com/forum1/viewtopic.php?f=31&t=3372>
EOF`
# バージョンメッセージ
versionMessage=`cat <<EOF
${name} version ${version} (update ${update})
\`gettext 'Licence'\`: CC-BY <https://creativecommons.org/licenses/by/4.0/>
\`gettext 'Using'\`: dpkg-deb, gettext, mksquashfs, sh, wget, etc
EOF`
# 変数を固定
readonly name version update helpMessage versionMessage
## 終了時に一時ディレクトリを削除する
endcall () {
[ -n "${verboseFlag-}" ] && transrate '# Remove temporary directory #'
rm -fr ${verboseFlag-} "${tmpDirectory}" "${tmpFile}"
}
## エラーメッセージを出力する
errorMessage () {
transrate "%s: ${1}" "${0}" 1>&2
transrate "Try \`%s --help' for more information" "${0}" 1>&2
# EX_USAGE (/usr/include/sysexits.h)
exit 64
}
## クォートをネストする
quote () {
echo "'`echo \"${1}\" | sed -re \"s/([']+)/'\\\"\1\\\"'/g\"`'"
}
## メッセージを翻訳する
transrate () {
message="${1}"
shift
printf "`gettext \"${message}\"`\n" "${@}"
}
# 引数の解析
while [ 0 -lt "${#}" ]; do
case "${1}" in
# Debianパッケージのcontrol
'-c' | '--control')
controlFlag=1
shift
;;
# ヘルプメッセージ
'-h' | '--help')
echo "${helpMessage}"
return 0
;;
# SquashFSを作成しない
'-n' | '--no-sfs')
nosfsFlag=1
shift
;;
# mksquashfsのオプション
'-o' | '--option')
# オプションに引数がなかった場合
[ "${#}" -lt 2 ] && {
errorMessage "option '${1}' requires an argument"
}
options="${options-} "`quote "-${2}" | sed -e "s/:/' '/"`
shift 2
;;
# 冗長な表示
'-v' | '--verbose')
verboseFlag='--verbose'
shift
;;
# バージョンメッセージ
'-V' | '--version')
echo "${versionMessage}"
return 0
;;
# 以降オプション以外の引数
'-' | '--')
shift
while [ 0 -lt "${#}" ]; do
parameters="${parameters-} "`quote "${1}"`
shift
done
;;
# ロングオプション
--[!-]*=*)
option="${1}"
shift
set -- "`echo \"${option}\" | cut -d = -f 1`" "`echo \"${option}\" | cut -d = -f 2-`" "${@}"
;;
# 複合ショートオプション
-[!-][!-]*)
option="${1}"
shift
set -- "-`echo \"${option}\" | cut -c 2`" "-`echo \"${option}\" | cut -c 3-`" "${@}"
;;
# 無効なオプション
-*)
errorMessage "unrecognized option '${1}'"
;;
# オプション以外の引数
*)
parameters="${parameters-} "`quote "${1}"`
shift
# POSIX標準ならば以降オプション以外の引数
[ "`printenv 'POSIXLY_CORRECT' > /dev/null; echo \"${?}\"`" -eq 0 -o "`printenv 'ADSH_CMD_ARGORDER'`" = 'seq' ] && {
set -- '--' "${@}"
}
;;
esac
done
# 変数を固定
readonly controlFlag nosfsFlag options parameters verboseFlag
# オプション以外の引数の存在を確認
[ -z "${parameters-}" ] && {
errorMessage 'missing arguments'
}
# 位置パラメータを再セット
eval "set ${parameters-}"
# 先頭の位置パラメータから宛先を取り出す
dest="${1}"
shift
# 一時ディレクトリを作成
[ -n "${verboseFlag-}" ] && transrate '# Make temporary directory #'
tmpDirectory=`mktemp -d`
tmpFile=`mktemp`
# 終了時に関数を呼び出す
trap "endcall" EXIT
trap "endcall; exit 129" 1
trap "endcall; exit 130" 2
trap "endcall; exit 131" 3
trap "endcall; exit 143" 15
# 変数を固定
readonly dest tmpDirectory tmpFile
# ${controlFlag}が有効ならば/etc/init.dを作成
[ "${controlFlag-0}" -eq 1 ] && {
initd="${tmpDirectory}/etc/init.d"
[ -n "${verboseFlag-}" ] && transrate '# Make %s directory #' '/etc/init.d'
mkdir -p ${verboseFlag-} "${initd}"
}
# 各Debianパッケージを処理
for deb; do
# 通信プロトコルならばタウンロード
`echo "${deb}" | grep -qE '^https?://|^ftps?://'` && {
[ -n "${verboseFlag-}" ] && transrate '# Download %s #' "${deb}"
wget -nv ${verboseFlag-} -O "${tmpFile}" "${deb}"
deb="${tmpFile}"
}
# Debianパッケージからファイルを取り出す
[ -n "${verboseFlag-}" ] && transrate '# Extract files in %s #' "${deb}"
dpkg-deb ${verboseFlag-} -x "${deb}" "${tmpDirectory}"
[ "${controlFlag-0}" -eq 1 ] && {
debname=`dpkg-deb -W --showformat='${Package}_${Version}_${Architecture}' "${deb}"`
control="${tmpDirectory}/var/run/deb2sfs.sh/${debname}"
[ -n "${verboseFlag-}" ] && transrate '# Make %s directory #' "/var/run/deb2sfs.sh/${debname}"
mkdir -p ${verboseFlag-} "${control}"
# Debianパッケージからコントロールファイルを取り出す
[ -n "${verboseFlag-}" ] && transrate '# Extract control file in %s #' "${deb}"
dpkg-deb ${verboseFlag-} -e "${deb}" "${control}"
# サービス起動スクリプトを作成
cat > "${initd}/${debname}.sh" <<EOF
#!/usr/bin/env sh
set -eu
control="/var/run/deb2sfs.sh/${debname}"
readonly control
case "\${1}" in
'start')
[ -x "\${control}/preinst" ] && "\${control}/preinst" 'install'
[ -x "\${control}/postinst" ] && "\${control}/postinst" 'configure' "\`grep -m 1 '^Version:' \"\${control}/control\" | sed -e 's/^Version:[ ]*//'\`"
;;
'stop')
[ -x "\${control}/prerm" ] && "\${control}/prerm" 'remove'
[ -x "\${control}/postrm" ] && "\${control}/postrm" 'remove'
;;
esac
EOF
[ -n "${verboseFlag-}" ] && transrate '# Chenge mod %s #' "/etc/init.d/${debname}.sh"
chmod ${verboseFlag-} 755 "${initd}/${debname}.sh"
}
done
# 一部ディレクトリの内容を上位ディレクトリに移動
for path in '/lib/i386-linux-gnu' '/usr/bin/i386-linux-gnu' '/usr/lib/i386-linux-gnu'; do
[ -d "${tmpDirectory}${path}" ] && {
[ -n "${verboseFlag-}" ] && transrate '# Move %s #' "${path}"
cp -afT ${verboseFlag-} "${tmpDirectory}${path}" "${tmpDirectory}${path}/.."
rm -fr ${verboseFlag-} "${tmpDirectory}${path}"
}
done
# ${nosfsFlag}による処理の分岐
if [ "${nosfsFlag-0}" -eq 1 ]; then
# 一時ディレクトリの内容をコピー
[ -n "${verboseFlag-}" ] && transrate '# Copy temporary directory to %s #' "${dest}"
cp -afT ${verboseFlag-} "${tmpDirectory}" "${dest}"
else
# SquashFSの作成
[ -n "${verboseFlag-}" ] && transrate '# Make %s #' "${dest}"
eval "mksquashfs \"${tmpDirectory}\" \"${dest}\" ${options-}"
fi
)
# メインの関数を呼び出す
deb2sfs "${@}"
実験的な機能ですが、`-c`オプションでDebianパッケージに含まれているコントロールファイル(preinst, postinst, prerm, postrm)をロード、アンロード時に自動的に実行させることができます。
`mksquashfs`コマンドにオプションを渡す場合は、`-o name[:value]`の形式で渡せます。`-n`オプションを付けるとSquashFSは作成されず、ディレクトリが作成されます。引数がURLであった場合、`wget`コマンドを使用してダウンロードを行います。
その他については`-h`オプションで簡単なヘルプを表示できます。
このスクリプトはPrecise-571JPで動作確認をしています。
あくまで見様見真似で悪戦苦闘しながら作成したものですので、バグや不具合、その他至らない点が多々あるかもしれません。その時はご報告頂ければ幸いでござます。
このスクリプトを作成するにあたっては、<viewtopic.php?f=12&t=3356>にてご回答いただきました、thinkpadnerdさん、ルビーさん、Zstepさんに改めて御礼申し上げます。この質問の解決なしに、このプログラムを作成することは不可能でした。