Возможно, что-то вроде этого?
find . -type f -exec 'rsync' '{}' ';'
Это выполнит rsync однажды для каждого регулярного файла под текущим каталогом, передавая имя файла (представленный {}
маркер) как параметр командной строки.
Если у Вас есть символьные ссылки, файлы устройств, и т.д. в соответствии с рассматриваемым каталогом, можно попытаться инвертировать логику:
find . -not -type f -exec 'rsync' '{}' ';'
Это должно "работать", в смысле выполнения, что Вы спрашиваете (запускающийся rsync однажды на файл). Но я получаю чувство, что Вы идете об этом неправильным путем.
rsync списки страницы справочника --timeout
(Тайм-аут ввода-вывода) и --contimeout
(тайм-аут соединения), и это только от захвата для timeout
. Вы рассмотрели использование их?
Рабочее решение использует patchelf
(если вам приходится иметь дело с несовпадающими версиями glibc: в хост-системе и в одной библиотеке nix, с которой были связаны ссылки), см. вторую половину моего рассказа.
Что ж, я установил для этого переменную окружения в ~ /.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)
$
Самая неожиданная ошибка здесь:
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 в одной системе возможно, но немного сложно, как объясняется в этом ответе.)
Итак, путь к динамическому компоновщику жестко запрограммирован в двоичном файле. И используемый динамический компоновщик берется из системы (с хоста 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
)
Аналогичным образом вы можете изменить RPATH
, путь поиска компоновщика, встроенный в исполняемые файлы и динамические библиотеки:
patchelf --set-rpath /opt/my-libs/lib:/foo/lib program
Это заставляет динамический компоновщик искать в / opt / my-libs / lib
и / foo / lib
общие библиотеки, необходимые программе. Конечно, вы также можете установить переменную среды LD_LIBRARY_PATH
, но это часто неудобно, поскольку для настройки среды требуется сценарий оболочки.
В дополнение к «одно- пользовательский режим », я отвечаю для пользователей 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
.