Decision
Here is my approach: parse the bash file itself and process only the variable destination lines, such as:
FOO="/path/to/foo"
Here is the code:
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)
How it works
Take a look at this snippet:
shell_vars = dict(parse_shell_var(line) for line in f if '=' in line)
This line is repeated through the lines in the shell script, processes only those lines that have an equal sign (not a reliable way to define variables, but the easiest). Then run these lines in the parse_shell_var function, which uses shlex.split to correctly handle quotes (or lack thereof). Finally, the parts are compiled into a dictionary. The result of this script is:
{'MOO': '/dont/have/a/cow', 'FOO': 'my variable foo', 'BAR': 'My variable bar'}
Here is the contents of shell_vars.sh:
FOO='my variable foo' BAR="My variable bar" MOO=/dont/have/a/cow echo $FOO
Discussion
This approach has several advantages:
- It does not execute a shell (either in bash or Python), which avoids any side effect
- Therefore, it is safe to use even if the source of the shell script is unknown.
- It correctly processes values โโwith or without quotation marks
This approach is not ideal, it has several limitations:
source share