Как пользоваться библиотеками, установленными, отклоняют во времени выполнения?

Возможно, что-то вроде этого?

find . -type f -exec 'rsync' '{}' ';'

Это выполнит rsync однажды для каждого регулярного файла под текущим каталогом, передавая имя файла (представленный {} маркер) как параметр командной строки.

Если у Вас есть символьные ссылки, файлы устройств, и т.д. в соответствии с рассматриваемым каталогом, можно попытаться инвертировать логику:

find . -not -type f -exec 'rsync' '{}' ';'

Это должно "работать", в смысле выполнения, что Вы спрашиваете (запускающийся rsync однажды на файл). Но я получаю чувство, что Вы идете об этом неправильным путем.

rsync списки страницы справочника --timeout (Тайм-аут ввода-вывода) и --contimeout (тайм-аут соединения), и это только от захвата для timeout. Вы рассмотрели использование их?

8
10.11.2016, 19:04
2 ответа

TL; DR

Рабочее решение использует patchelf (если вам приходится иметь дело с несовпадающими версиями glibc: в хост-системе и в одной библиотеке nix, с которой были связаны ссылки), см. вторую половину моего рассказа.

Попытка обычного подхода

Попытка использовать LD_LIBRARY_PATH

Что ж, я установил для этого переменную окружения в ~ /.bash_profile :

NIX_LINK=/home/ivan/.nix-profile
export LD_LIBRARY_PATH="$NIX_LINK"/lib

но это еще не все!

Теперь возникли проблемы с компоновкой с разными версиями libc :

$ ldd -r ../valencies 
../valencies: /lib64/libc.so.6: version `GLIBC_2.15' not found (required by ../valencies)
../valencies: /lib64/libc.so.6: version `GLIBC_2.14' not found (required by ../valencies)
../valencies: /lib64/libc.so.6: version `GLIBC_2.14' not found (required by /home/ivan/.nix-profile/lib/libgmp.so.10)
    linux-vdso.so.1 =>  (0x00007fff365ff000)
    /usr/local/lib/libsnoopy.so (0x00007f56c72e6000)
    libgmp.so.10 => /home/ivan/.nix-profile/lib/libgmp.so.10 (0x00007f56c7063000)
    libffi.so.5 => /usr/lib64/libffi.so.5 (0x00007f56c6e54000)
    libm.so.6 => /lib64/libm.so.6 (0x00007f56c6bd0000)
    librt.so.1 => /lib64/librt.so.1 (0x00007f56c69c7000)
    libdl.so.2 => /lib64/libdl.so.2 (0x00007f56c67c3000)
    libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f56c65a6000)
    libc.so.6 => /lib64/libc.so.6 (0x00007f56c6211000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f56c74f1000)
symbol memcpy, version GLIBC_2.14 not defined in file libc.so.6 with link time reference    (/home/ivan/.nix-profile/lib/libgmp.so.10)
symbol memcpy, version GLIBC_2.14 not defined in file libc.so.6 with link time reference    (../valencies)
symbol __fdelt_chk, version GLIBC_2.15 not defined in file libc.so.6 with link time reference   (../valencies)
$ 

Сортировка двух версий glibc

Самая неожиданная ошибка здесь:

symbol memcpy, version GLIBC_2.14 not defined in file libc.so.6 with link time reference    (/home/ivan/.nix-profile/lib/libgmp.so.10)

потому что nix ] должна быть установлена ​​версия glibc , которая используется его libgmp !

И действительно, glibc из nix есть:

$ ldd -r /home/ivan/.nix-profile/lib/libgmp.so.10
    linux-vdso.so.1 =>  (0x00007fff0f1ff000)
    /usr/local/lib/libsnoopy.so (0x00007f06e9919000)
    libc.so.6 => /nix/store/93zfs0zzndi7pkjkjxawlafdj8m90kg5-glibc-2.20/lib/libc.so.6 (0x00007f06e957c000)
    libdl.so.2 => /lib64/libdl.so.2 (0x00007f06e9371000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f06e9da7000)
symbol _dl_find_dso_for_object, version GLIBC_PRIVATE not defined in file ld-linux-x86-64.so.2 with link time reference (/nix/store/93zfs0zzndi7pkjkjxawlafdj8m90kg5-glibc-2.20/lib/libc.so.6)
/home/ivan/.nix-profile/lib/libgmp.so.10: error while loading shared libraries: __vdso_time: invalid mode for dlopen(): Invalid argument
$ 

Возможно, glibc был недоступен для пользователя, поэтому, когда я запустил свой двоичный сначала загружался системный glibc . Доказательство:

$ ls ~/.nix-profile/lib/*libc*
ls: cannot access /home/ivan/.nix-profile/lib/*libc*: No such file or directory
$ 

Хорошо, мы можем попробовать сделать glibc видимым для пользователя:

$ nix-env -i glibc

Тогда все плохо:

$ ldd -r ../valencies 
/bin/bash: error while loading shared libraries: __vdso_time: invalid mode for dlopen(): Invalid argument
$ /bin/echo ok
/bin/echo: error while loading shared libraries: __vdso_time: invalid mode for dlopen(): Invalid argument
$ 

Так что, если хотите, это кажется непростой задачей для загрузки библиотек из nix при запуске ваших собственных двоичных файлов ...

А пока я комментирую

export LD_LIBRARY_PATH="$NIX_LINK"/lib

и делаю в сеансе оболочки:

$ unset LD_LIBRARY_PATH
$ export LD_LIBRARY_PATH

Нужно подумать больше. (Прочтите о __ vdso_time: недопустимый режим для dlopen () : наличие другого glibc в LD_LIBRARY_PATH , как ожидается, выйдет из строя, потому что ваш ld-linux-x86 -64.so.2 не будет соответствовать вашему libc.so.6 . Наличие нескольких версий glibc в одной системе возможно, но немного сложно, как объясняется в этом ответе.)

Необходимое решение: patchelf

Итак, путь к динамическому компоновщику жестко запрограммирован в двоичном файле. И используемый динамический компоновщик берется из системы (с хоста glibc), а не из nix. И поскольку динамический компоновщик не соответствует glibc, который мы хотим и должны использовать, он не работает.

Простое и рабочее решение - patchelf .

patchelf --set-interpreter /home/ivan/.nix-profile/lib/ld-linux-x86-64.so.2 ../valencies

После этого все работает. Однако вам все еще нужно возиться с LD_LIBRARY_PATH .

$ LD_LIBRARY_PATH=/home/ivan/.nix-profile/lib:/lib64/:/usr/lib64/ ../valencies

Если - как в моем несовершенном случае - некоторые библиотеки взяты из nix, а некоторые из хост-системы (потому что я не установил их с помощью nix-env -i ), вы должны указать путь к библиотекам nix и к библиотекам вашей хост-системы в LD_LIBRARY_PATH (он полностью отменяет путь поиска по умолчанию).

дополнительный шаг: patchelf для пути поиска библиотеки

(со страницы patchelf )

Аналогичным образом вы можете изменить RPATH , путь поиска компоновщика, встроенный в исполняемые файлы и динамические библиотеки:

patchelf --set-rpath /opt/my-libs/lib:/foo/lib program

Это заставляет динамический компоновщик искать в / opt / my-libs / lib и / foo / lib общие библиотеки, необходимые программе. Конечно, вы также можете установить переменную среды LD_LIBRARY_PATH , но это часто неудобно, поскольку для настройки среды требуется сценарий оболочки.

7
27.01.2020, 20:11

В дополнение к «одно- пользовательский режим », я отвечаю для пользователей NixOS . Обычно вы не можете запускать двоичные файлы на NixOS.

Если вы устанавливаете пакеты локально с помощью nix-env -i , все ваши .so файлы хранятся в ~ / .nix-profile / lib / .

Если вы устанавливаете пакеты глобально , указав их в /etc/nixos/configuration.nix , ваши соответствующие файлы .so можно найти в ] / nix / var / nix / profiles / system / sw / lib / . Точнее, только символические ссылки на соответствующие файлы где-то в / nix / store / находятся в этом каталоге.

Итак, если вы устанавливаете пакеты глобально, решение Ивана Захарьящева будет выглядеть так:

$ patchelf --set-interpreter /nix/var/nix/profiles/system/sw/lib/ld-linux-x86-64.so.2 ./YOUREXECUTABLE
$ LD_LIBRARY_PATH=/nix/var/nix/profiles/system/sw/lib ./YOUREXECUTABLE

Чтобы первая команда работала, вам необходимо установить glibc глобально. Вы также можете изменить вторую команду, если у вас есть пакеты, установленные как глобально, так и для каждого пользователя:

$ LD_LIBRARY_PATH=/home/YOURUSERNAME/.nix-profile/lib:/nix/var/nix/profiles/system/sw/lib ./YOUREXECUTABLE

Возможно, необходимый файл .so просто не установлен в системе, поэтому вы есть ошибка типа:

./YOUREXECUTABLE: error while loading shared libraries: libX11.so.6: cannot open shared object file: No such file or directory

Я не знаю, как найти соответствующий пакет для отсутствующего файла в целом, но вы можете погуглить имя файла .so , установить соответствующий пакет и попробовать чтобы снова запустить исполняемый файл с пользовательским LD_LIBRARY_PATH .

3
27.01.2020, 20:11

Теги

Похожие вопросы