Я использую 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 в случае, если кто-то делает что-то хитрое с текущим рабочим каталогом.

Другие вопросы по тегам