Gentoo Prefix on MaxOSXでpython-updaterにハマった

Gentooでemergeしてますか?

Gentoo Prefix on MacOSXpython-updaterを実行したところ

$ python-updater
 * Starting Python Updater...
 * Main active version of Python:  2.7
 * Active version of Python 2:     2.7
 * Active version of Python 3:     3.2
./python-updater.old: 行 628: scantool: コマンドが見つかりません
./python-updater.old: 行 687: scantool: コマンドが見つかりません
./python-updater.old: 行 628: scantool: コマンドが見つかりません
./python-updater.old: 行 687: scantool: コマンドが見つかりません
./python-updater.old: 行 628: scantool: コマンドが見つかりません
./python-updater.old: 行 687: scantool: コマンドが見つかりません
./python-updater.old: 行 628: scantool: コマンドが見つかりません
./python-updater.old: 行 687: scantool: コマンドが見つかりません
./python-updater.old: 行 628: scantool: コマンドが見つかりません
./python-updater.old: 行 687: scantool: コマンドが見つかりません
./python-updater.old: 行 628: scantool: コマンドが見つかりません
./python-updater.old: 行 687: scantool: コマンドが見つかりません
^C

おおう、実行できないじゃないですか。
scantoolってなんぞ? と思って中身はシェルスクリプトなのでpython-updaterの中身を見てみる

...
einfo $'\e[1;36m'"Active version of Python 3:     ${NEW_PYTHON3_VERSION:-(None)}"$'\e[0m'

scantool=
if type -P scanelf >/dev/null 2>&1; then
    scantool=scanelf
elif type -P scanmacho >/dev/null 2>&1; then
    scantool=scanmacho
fi
if [[ CHECK_SHARED_LINKING -ne 0 ]]; then
    if [[ -z ${scantool} ]] ; then
...

とある。
scanelfとscanmachoについてmanを見てみる。

NAME
       scanelf - user-space utility to scan ELF files

DESCRIPTION
       scanelf is a user-space utility to quickly scan given ELFs, directories, or common system paths for different information. This may include ELF
       types, their PaX markings, TEXTRELs, etc...
NAME
       scanmacho - user-space utility to scan Mach-O files

DESCRIPTION
       scanmacho is a user-space utility to quickly scan given Mach-Os, directories, or common system paths for different information. This may include
       Mach-O types, their install_names, etc...

       Because Mach-O files can be "fat", it is possible for a single file to return multiple lines. Each line represents a single architecture, contained
       in the fat (universal) file. While there are no real restrictions, in practice, the entries can be distinguished by their arch type, e.g. ppc, ppc64,
       i386, x86_64, arm, ...

manが見れるんだからどちらも存在してるしエラーが出るのはおかしい。
先ほどあげたif文を改めて見ると

  • scanelfがあればscantoolにscanelfという文字列を代入
  • scanmachoがあればscantoolにscanmachoという文字列を代入

このへんは大丈夫っぽい。
じゃあ実際にエラーが起きてる628行目と687行目を見てみる。

...
        if [[ CHECK_STATIC_LINKING -ne 0 ]]; then
                binaries="$(scantool -qs +Py_Initialize < <(grep -E "^obj" "${content}" | cut -d" " -f2 | grep -Ev "^/Users/nana4gonta/Gentoo/usr/lib(32|64)?/debug/") | sed "s/.* //")"
                if [[ -n "${binaries}" ]]; then
                        PKGS_TO_REMERGE+=" ${CATPKGVER}"
...
...
        fi

        if [[ CHECK_SHARED_LINKING -ne 0 ]]; then
                binaries="$(scantool -qF "%F %n" < <(grep -E "^obj" "${content}" | cut -d" " -f2 | grep -Ev "^/Users/nana4gonta/Gentoo/usr/lib(32|64)?/debug/") | grep -E "( |,)$(get_OLD_PYTHON_SHARED_LIBRARIES_REGEX)(,|$)")"
                if [[ -n "${binaries}" ]]; then
                        PKGS_TO_REMERGE+=" ${CATPKGVER}"
...

あれ?これ$(scantool ...)としてもコマンドとして実行されないような...?

$ export hoge=emacs
$ $(hoge)
bash: hoge: コマンドが見つかりません
$ $(hoge -q)
bash: hoge: コマンドが見つかりません
$ $($hoge -q)

Emacsさんに犠牲になってもらいましたが、$()で囲んだだけだとhogeコマンドとして認識されるみたいです。
つまりpython-updaterの中でもscantoolというコマンドを探してエラーになってるみたいですね。
ということで以下のように修正してみました。

--- python-updater.old	2011-12-08 22:01:02.000000000 +0900
+++ ~/Gentoo/usr/sbin/python-updater	2011-12-06 02:13:35.000000000 +0900
@@ -625,7 +625,7 @@
 	fi
 
 	if [[ CHECK_STATIC_LINKING -ne 0 ]]; then
-		binaries="$(scantool -qs +Py_Initialize < <(grep -E "^obj" "${content}" | cut -d" " -f2 | grep -Ev "^/Users/kazuhiro/Gentoo/usr/lib(32|64)?/debug/") | sed "s/.* //")"
+		binaries="$(${scantool} -qs +Py_Initialize < <(grep -E "^obj" "${content}" | cut -d" " -f2 | grep -Ev "^/Users/kazuhiro/Gentoo/usr/lib(32|64)?/debug/") | sed "s/.* //")"
 		if [[ -n "${binaries}" ]]; then
 			PKGS_TO_REMERGE+=" ${CATPKGVER}"
 			eindent
@@ -684,7 +684,7 @@
 	fi
 
 	if [[ CHECK_SHARED_LINKING -ne 0 ]]; then
-		binaries="$(scantool -qF "%F %n" < <(grep -E "^obj" "${content}" | cut -d" " -f2 | grep -Ev "^/Users/kazuhiro/Gentoo/usr/lib(32|64)?/debug/") | grep -E "( |,)$(get_OLD_PYTHON_SHARED_LIBRARIES_REGEX)(,|$)")"
+		binaries="$(${scantool} -qF "%F %n" < <(grep -E "^obj" "${content}" | cut -d" " -f2 | grep -Ev "^/Users/kazuhiro/Gentoo/usr/lib(32|64)?/debug/") | grep -E "( |,)$(get_OLD_PYTHON_SHARED_LIBRARIES_REGEX)(,|$)")"
 		if [[ -n "${binaries}" ]]; then
 			PKGS_TO_REMERGE+=" ${CATPKGVER}"
 			eindent

これでとりあえずpython-updaterがGentoo Prefixで使えますね。
ちなみにamd64Gentooマシンで同様の行がどうなってるか見てみましょう。

...
        fi

        if [[ CHECK_STATIC_LINKING -ne 0 ]]; then
                binaries="$(scanelf -qs +Py_Initialize < <(grep -E "^obj" "${content}" | cut -d" " -f2 | grep -Ev "^/usr/lib(32|64)?/debug/") | sed "s/.* //")"
                if [[ -n "${binaries}" ]]; then
                        PKGS_TO_REMERGE+=" ${CATPKGVER}"
...

あっ、scanelfコマンドベタ打ちだった!