Почему mkdir -p не работает правильно в скрипте, вызываемом checkinstall? - PullRequest
7 голосов
/ 12 февраля 2011

Я пытаюсь скомпилировать Квартал и упаковать его, используя checkinstall .

Если я делаю стандартную установку ./configure && make && sudo make install, все идет хорошо.

$ wget http://ftp.coin3d.org/coin/src/all/Quarter-1.0.0.tar.gz
$ tar xzf Quarter-1.0.0.tar.gz
$ cd Quarter-1.0.0
$ ./configure
$ make
$ sudo make install

Но когда я использую checkinstall, он выходит из строя на mkdir -p, который должен работать идеально. Он терпит неудачу именно так, как если бы опция -p не была указана. Это командная строка checkinstall, которую я использую:

$ checkinstall -D -y --install=no --pkgname=libquarter --pkgversion=1.0.0 \
  --arch=i386 --pkglicense=GPL --maintainer=me@example.com --reset-uids=yes

Это ошибка:

....
/bin/bash ../../../cfg/mkinstalldirs /usr/local/include/Quarter/devices
mkdir -p -- /usr/local/include/Quarter/devices
mkdir: cannot create directory `/usr/local/include/Quarter': No such file or directory
make[4]: *** [install-libdevicesincHEADERS] Error 1
....

Это соответствующая часть сценария:

$ cat cfg/mkinstalldirs
....
case $dirmode in
  '')
    if mkdir -p -- . 2>/dev/null; then
      echo "mkdir -p -- $*"
      exec mkdir -p -- "$@"
    fi
    ;;
....

Я не понимаю, почему это exec существует - разве это не гарантирует, что оставшаяся часть сценария (после esac) никогда не будет выполнена? (Если if тест пройден, затем сценарий предполагает, что mkdir -p работает правильно, поэтому, как только он выполнит реальное mkdir -p, он может выйти, в противном случае остальная часть сценария реализует правильное mkdir -p поведение.) Я тоже не понимаю почему он использует "$*" в echo и "$@" в следующей строке, но, похоже, это не имеет значения - они оба одинаковы, так как этот скрипт вызывается только с одним аргументом. ( Том объяснил в комментарии.)

Если я добавлю две строки между echo и exec, что делает mkdir -p -- "$@", а затем echo "Now doing the exec mkdir...", тогда это будет работать так - лучше, но все еще сбивает с толку:

/bin/bash ../../../cfg/mkinstalldirs /usr/local/include/Quarter/devices
mkdir -p -- /usr/local/include/Quarter/devices
mkdir: cannot create directory `/usr/local/include/Quarter': No such file or directory
Now doing the exec mkdir...
 /usr/bin/install -c -m 644 InputDevice.h /usr/local/include/Quarter/devices/InputDevice.h
.... finishes successfully!

Теперь тот факт, что выполнение строки mkdir дважды заставило ее работать, говорит мне, что это не проблема с разрешениями (кроме того, это вызвало бы другую диагностику из mkdir, и она запускается как sudo, и она фактически работает в /var/tmp/... не настоящий /usr/local/...). Я думаю, что происходит то, что первый вызов mkdir (тот, который я добавил) фактически создает только каталог Quarter и выручает, а затем, когда запускается второй mkdir, он может создать подкаталог devices, потому что Quarter каталог уже есть. Но почему mkdir так работает ???

Мой обходной путь - как-то исправить этот скрипт mkinstalldirs, но мне действительно любопытно, почему он ломается!

Это гость Ubuntu 10.10, работающий в VirtualBox на Win7, проверьте установку версии 1.6.2 через apt-get.


EDIT: Я провел некоторое тестирование, чтобы увидеть, что работает и что не работает в этой среде ...

mkdir -p /foo works correctly
mkdir -p /foo && mkdir -p /foo/bar works correctly
mkdir -p foo/bar works correctly
mkdir /foo/bar failed as expected (correct)
mkdir foo/bar failed as expected (correct)
mkdir -p /foo/bar fails

Странно, что -p работает для относительных имен путей, но не для абсолютных имен путей. Или, возможно, правильное различие заключается в том, что -p работает вне дерева "chroot" (если оно действительно использует chroot), но не внутри него.

Я также проверил, что, несмотря на ошибку, он может создать первый уровень каталога.

Все еще остается загадкой.

Ответы [ 3 ]

21 голосов
/ 26 октября 2011

Использование

checkinstall --fstrans=no

должно исправить это.Или

Set "TRANSLATE=0"

в /etc/checkinstallrc и повторите попытку.

2 голосов
/ 12 февраля 2011

mkdir -p работает не так, как должно, потому что это версия mkdir с проверкой установки, а не "истинный" mkdir.Должна быть какая-то ошибка в checkinstall, которая заставляет его работать немного по-другому.

Этот патч работает вокруг ошибки:

./configure
sed -i 's/if mkdir .*-p --.*; then/if false; then ## &/' cfg/mkinstalldirs
....
0 голосов
/ 02 ноября 2014
sed -i -e 's/TRANSLATE=1/TRANSLATE=0/g' /etc/checkinstallrc
...