Решение
Вот мой подход: разобрать Баш файл Мыс Эльф и процесс только переменные линии назначения, такие как:
FOO="/path/to/foo"
Вот код:
import shlex
def parse_shell_var(line):
"""
Parse such lines as:
FOO="My variable foo"
:return: a tuple of var name and var value, such as
('FOO', 'My variable foo')
"""
return shlex.split(line, posix=True)[0].split('=', 1)
if __name__ == '__main__':
with open('shell_vars.sh') as f:
shell_vars = dict(parse_shell_var(line) for line in f if '=' in line)
print(shell_vars)
Как это работает
Посмотрите на этот фрагмент:
shell_vars = dict(parse_shell_var(line) for line in f if '=' in line)
Эта строка выполняет итерации по строкам в сценарии оболочки, обрабатывает только те строки, которые имеют знак равенства (а не foo l-proof способ обнаружения переменных, но самый простой). Затем запустите эти строки в функции parse_shell_var
, которая использует shlex.split
, чтобы правильно обрабатывать кавычки (или их отсутствие). Наконец, части собраны в словарь. Вывод этого сценария:
{'MOO': '/dont/have/a/cow', 'FOO': 'my variable foo', 'BAR': 'My variable bar'}
Вот содержание shell_vars.ш:
FOO='my variable foo'
BAR="My variable bar"
MOO=/dont/have/a/cow
echo $FOO
Обсуждение
Этот подход имеет несколько преимуществ:
- Он не выполняет оболочки (либо в баш или Python), что позволяет избежать любой побочный эффект
- Следовательно, он безопасен в использовании, даже если источник сценария оболочки неизвестен
- Он правильно обрабатывает значения с или без кавычек эс
Этот подход не является совершенным, он имеет несколько ограничений:
- Метод определения переменной назначения (путем поиска на наличие знака равенства) примитивна и не точны. Есть способы лучше определить эти строки, но это тема для другого дня.
Он неправильно анализирует значения, которые основаны на других переменных или командах. Это означает, что она не будет выполнена для линий, таких как:
FOO=$BAR
FOO=$(pwd)
хорошей работы токарных нонсенс ответ на правильный. – dbliss
Конечно, это, как правило, очень плохая идея, если у вас нет полного контроля над вашими входными данными (в этом случае, пойдите, я думаю). – larsks
Это не плохой ответ (он * допустим), но обычные оговорки должны быть там. – Harlin