Могу ли я использовать псевдоним для выполнения программы из сценария Python - PullRequest
9 голосов
/ 28 июля 2011

Я почти новичок в написании скриптов на Python, поэтому прошу прощения за любые глупые вопросы, но любая помощь, которую кто-либо может дать, будет высоко ценится.

Я пытаюсь написать скрипт на Python для использования другими людьми,и в нем мне нужно вызвать программу, к которой я не всегда знаю путь.Чтобы обойти это, я прошу пользователя указать путь к программе, которая будет работать, но я не хочу, чтобы пользователи указывали путь КАЖДЫЙ раз, когда они запускают скрипт, поэтому я пытался настроить bashдобавив псевдоним в файлы ~ / .profile и ~ / .bashrc.

Затем я могу использовать псевдоним для запуска программы из интерактивной оболочки bash, но когда скрипт пытается ее запустить,Я получаю сообщение об ошибке "команда не найдена" ...

Я попытался повторно получить файл .bashrc и безуспешно использовать команду "shopt -s expand_aliases".

My ~/.bashrc выглядит так:

alias nuke='/Applications/Nuke6.2v4/Nuke6.2v4.app/Contents/MacOS/Nuke6.2v4'

И фрагмент скрипта выглядит так:

os.system('source .bashrc')
os.system('shopt -s expand_aliases')
os.system('nuke -x scriptPath')

Но как только сценарий дойдет до этой точки, он вернет:

sh: nuke: command not found

Я делаю что-то не так или есть другой способ, которым я могу навсегда сохранить путь к программе?

Ответы [ 5 ]

15 голосов
/ 28 июля 2011

Модуль, который вам нужен - это подпроцесс .

Быстрое решение вашей проблемы - использовать модуль подпроцесса, например:

import subprocess
sp = subprocess.Popen(["/bin/bash", "-i", "-c", "nuke -x scriptpath"])
sp.communicate()

Это эквивалентно звонку:

nuke -x scriptpath

из оболочки bash. Флаг -i говорит bash вести себя так, как будто это интерактивный сеанс (и использовать файл ~ / .bashrc)

НО, вы должны быть очень осторожны, чтобы не открывать себя для каких-либо инъекций оболочки (например, если эта команда вызывается со страницы CGI)

Для быстрых уведомлений, которые пользователи вызывают непосредственно из оболочки, они, вероятно, не смогут нанести больше вреда, чем при обычном доступе к оболочке, но если этот сценарий вызывается веб-страницей, злоумышленник может передать что-то вроде " rm -dfr ~ / & "как программа. *

Если количество исполняемых файлов невелико, возможно, было бы лучше, если бы они назывались в сценарии:

PROGRAMS = {"nuke": "/path/to/nuke"
                "foo" : "/path/to/foo" }

# Parse command line args
program = sys.argv[1] 

sp = subprocess.Popen([PROGRAMS[program], "other", "arguments", "to", "program"])

* Это может работать не совсем так, но вы поняли

2 голосов
/ 29 августа 2014

Я знаю, что это старый вопрос, но для тех, кто сталкивается с этим в будущем, я думаю, стоит упомянуть, что изменение чьих-либо файлов ~ / .bashrc или ~ / .profile (особенно тихо) является одной из этих идей. это обычно подпадает под зонтик "плохой практики". Кроме того, он кажется немного сложным для решения проблемы, которую нужно решить.

Вместо этого, почему бы вашему скрипту не отслеживать свой собственный файл конфигурации, хранящийся в домашнем каталоге пользователя? Было бы довольно просто сделать это, используя ConfigParser, свою собственную структуру JSON, выгруженную в файл, или что-то еще, если хотите.

Затем в вашем скрипте вы можете сначала проверить, существует ли он, и если он существует, посмотреть, содержит ли он искомый ключ, содержащий путь к исполняемому файлу. Если какой-либо из этих тестов не пройден, вы знаете, что вам нужно запросить у пользователя путь, после чего вы сможете записать его в файл конфигурации в следующий раз.

2 голосов
/ 28 июля 2011

Имейте в виду, что os.system, вероятно, использует sh, а не bash, и поэтому source и shopt также не удастся выполнить.

Если это равно с помощью bash произойдет сбой, поскольку os.system создает новый процесс для каждого вызова.Вы можете сделать это в одной строке, например:

os.system('source .bashrc; shopt -s expand_aliases; nuke -x scriptPath')

Но вы на далеко лучше всего получите путь другим способом (или даже прочитаете его из .bashrc вручную, есливы хотите), а затем используйте subprocess.Popen().

0 голосов
/ 06 августа 2011

Я думаю, что псевдоним - это очень сложный и не очень интуитивно понятный способ использования среды оболочки. Как насчет использования переменных среды вместо этого? Это в основном то, для чего они ...

Вместо того, чтобы просить пользователей определить псевдоним nuke, попросите их определить переменную среды $NUKE. Это избавит вас от возни с .bashrc или любым другим файлом конфигурации. Если пользователь добавляет export NUKE=<path> к своему .bashrc, он автоматически становится доступным в среде при интерактивном выполнении сценария python.

Если вам нужен только этот путь для системного вызова, просто используйте os.system('$NUKE -x scriptPath').

Если вам нужно значение в python, к нему также легко получить доступ: после import os, os.environ дает вам словарь всех переменных среды, определенных в настоящее время. Получение значения, для которого задан псевдоним, в Python очень громоздко.

0 голосов
/ 28 июля 2011

Да, не делай этого. Запишите свою конфигурацию в свой собственный файл точек и не используйте os.system, используйте subprocess.

...