Я использую os.system для запуска исполняемого файла, но ему нужен файл.so, он не может найти библиотеку
Когда я вызываю исполняемый файл в Python, используя os.system("./mydemo")
в Ubuntu он не может найти файл.so (libmsc.so), необходимый для mydemo. я использовал os.system("export LD_LIBRARY_PATH=pwd:$LD_LIBRARY_PATH;")
, но он все еще не может найти libmsc.so.
Libmsc.so находится в текущем каталоге. и не должно быть глобальным.
3 ответа
Когда вы делаете os.system("export LD_LIBRARY_PATH=pwd:$LD_LIBRARY_PATH;")
, вы запускаете новый экземпляр оболочки, измените LD_LIBRARY_PATH
там, чем сразу выйти из него. Кроме того, pwd ничего не значит в контексте Python.
Попробуйте установить переменные env следующим образом:
os.system("LD_LIBRARY_PATH={} ./mydemo".format(os.getcwd()))
Или, может быть, лучше использовать модуль подпроцесса?
import subprocess
env = os.environ.copy()
env['LD_LIBRARY_PATH'] = os.getcwd()
proc = subprocess.Popen("./mydemo", shell=True, env=env)
proc.wait()
Если я правильно помню, выполнение export ...
с помощью os.system
будет только устанавливать эту переменную оболочки в области видимости, поэтому она не доступна в следующих os.system
прицелы. Вы должны установить LD_LIBRARY_PATH
в оболочке, перед выполнением скрипта Python.
Btw. также избегайте установки относительных путей…
Проблема в том, что export
экспортирует только свои переменные дочерним элементам текущей оболочки. Как в оболочке, которую вы создали, вызвав os.system
, который затем сразу выходит.
Если вы хотите самое простое исправление, чтобы сделать эту работу, вы можете сделать как export
и целевая программа внутри одной оболочки:
os.system("export LD_LIBRARY_PATH=pwd:$LD_LIBRARY_PATH; ./mydemo")
Есть некоторые другие проблемы с этим. Например, export
и присвоение переменной в той же команде является bash
-изм, который может быть недоступен во всех оболочках. С subprocess
Вы можете указать конкретную оболочку, но с system
вы просто получаете то, что ОС считает оболочкой по умолчанию - в Linux на странице руководства сказано, что это означает /bin/sh -c
,
На самом деле, лучший способ решить эту проблему - просто не использовать оболочку, а устанавливать переменные окружения так, как вы хотите. Именно поэтому os.system
Документы говорят: " subprocess
модуль предоставляет более мощные средства для порождения новых процессов и получения их результатов; использование этого модуля предпочтительнее, чем использование этой функции."Например:
env = dict(os.environ)
env['LD_LIBRARY_PATH'] = '"{}":{}'.format(
os.getcwd(), env.get('LD_LIBRARY_PATH', ''))
subprocess.check_call(['./mydemo'], env=env)
Или, если вы хотите быть действительно безопасным (в отличие от вашего шелл-кода):
LD_LIBRARY_PATH = env.get('LD_LIBRARY_PATH', '')
if LD_LIBRARY_PATH:
LD_LIBRARY_PATH = ':' + LD_LIBRARY_PATH
LD_LIBRARY_PATH = shlex.quote(os.getcwd()) + LD_LIBRARY_PATH
subprocess.check_call(['./mydemo'], env=env)
Я написал это более явно и многословно, чем вы обычно пишете, чтобы сделать шаги очевидными: не включайте в конце :
перед пустым путем, и использовать shlex.quote
в случае, если кто-то делает что-то хитрое с текущим рабочим каталогом.