#linux #bash #shell #ld
#linux #bash #оболочка #ld
Вопрос:
У меня есть скрипт bash, который запускает эту строку кода:
LD_LIBRARY_PATH=/tools/cluster/6.2/openbabel/2.3.2/lib ./xattr infile.txt outfile.txt
Если бы я вызвал эту строку непосредственно из оболочки, она работает нормально. Однако, если я запускаю его в скрипте bash, я получаю эту ошибку:
update.sh: line 45: LD_LIBRARY_PATH=/tools/cluster/6.2/openbabel/2.3.2/lib: No such file or directory
Почему LD_LIBRARY_PATH не работает, когда он установлен в сценарии bash?
Вот еще часть кода в строке 45:
BASE_DIR="/volatile/huanlab/bold/kendal/bioinformatics_database/tmp"
COMP_DIR="$BASE_DIR/compound"
# move to the current directory where xattr.cpp and other files are
cd /users/kharland/software/programs/BioDB-update/dev
# Compile xattr ('make xattr' is the same command I call from the shell
# to compile this program when this program actually works).
make xattr
# loop over each .sdf file in COMP_DIR
for INF in $(ls $COMP_DIR | grep sdf)
do
babel -isdf $COMP_DIR/$INF -ocan $SMILES_DIR/$INF.csv
LD_LIBRARY_PATH=/tools/cluster/6.2/openbabel/2.3.2/lib ./xattr $COMP_DIR/$INF $COMP_DIR/$COMP_FILE
done
Содержимое перед этими строками — это просто комментарии
Редактировать
В моем makefile я компилирую с этими параметрами
LDLIBS=-lm -ldl -lz -lopenbabel
LDFLAGS=-Wl,-rpath,/tools/cluster/6.2/openbabel/2.3.2/lib:/tools/cluster/system/pkg/openbabel/openbabel-2.3.2/build/lib,-L/tools/cluster/6.2/openbabel/2.3.2/lib
и запуск ldd xattr
показывает, что библиотеки действительно связаны, поэтому программа выполняется, как и ожидалось, при вызове из оболочки. Единственная проблема связана со сценарием bash. Если я удалю параметр LD_LIBRARY_PATH из сценария bash, я получаю проблему, из-за которой общие библиотеки для openbabel не найдены, хотя ldd показывает, что xattr знает, где находятся библиотеки. Вот почему я добавил LD_LIBRARY_PATH в сценарий bash, я пытаюсь использовать его в качестве обходного пути
Редактировать
(исправлена ошибка: заменены «библиотеки» на «мой код» ниже)
(указано неправильное имя файловой системы ниже)
Мне только что пришло в голову кое-что. Мой исходный код находится в /users
файловой системе. Если мои библиотеки находятся в другой смонтированной файловой системе, будут ли у bash проблемы с поиском этих документов?
Комментарии:
1. Можете ли вы поделиться большим фрагментом обновления. sh вокруг строки 45?
2. Вы уверены, что bash запускает скрипт?
3. @Kenster этот скрипт вызывается «update.sh » и я призываю
bash update.sh
запустить его.4. Сообщение об ошибке указывает, что оболочка обрабатывает часть LD_LIBRARY_PATH=… как команду для запуска, и ей не удается найти файл с этим именем. Я спросил о оболочке, потому что некоторые старые оболочки (например, Bourne shell, я думаю) не поддерживают синтаксис «FOO = bar some-command».
5. К вашему сведению,
for INF in $(ls $COMP_DIR | grep sdf)
это ошибка. Вам было бы лучшеfor inf in "$COMP_DIR"/*sdf*; do ...
; см. mywiki . wooledge.org/ParsingLs для более подробного объяснения.
Ответ №1:
Установка переменных среды работает в сценариях bash.
Попробуйте это:
#!/bin/bash
VAR1=VALUE1 env
… запустите этот скрипт, и вы увидите вывод, который включает VAR1
в себя и его значение.
Вообще говоря, это также работает с LD_LIBRARY_PATH
:
#!/bin/bash
tempdir=$(mktemp -t -d testdir.XXXXXX)
LD_LIBRARY_PATH=$tempdir env
rm -rf "$tempdir"
Если вы можете сгенерировать минимальный репродуктор, в котором этого не происходит, это было бы полезно и оценено.
Комментарии:
1. Это правильный ответ. Краткое объяснение: в моем оригинальном сценарии
LD_LIBRARY_PATH
инструкция интерпретировалась как команда вместо назначения переменной среды.2. @kjh, мне любопытно, как и почему ваш оригинальный скрипт генерировал такое поведение; если вы выясните, как его воспроизвести, пожалуйста, следуйте здесь.