I want to split a string into command-line arguments, exactly like shlex.split does. However, shlex doesn't seem to convert environment variables (for example $USER), and the output makes it impossible to know whether the environment variable was escaped:
>>> print(shlex.split("My name is Alice"))
['My', 'name', 'is', 'Alice']
>>> print(shlex.split("My name is '$USER'"))
['My', 'name', 'is', '$USER']
>>> print(shlex.split("My name is $USER")) # expected Alice, not $USER
['My', 'name', 'is', '$USER']
Is there a way to achieve this? (hopefully without re-implementing the whole thing)
Also, why doesn't shlex.split do this by default in the first place?
If it matters, I am using Python 3.6.8.
The argument passed into
shlex.split()is a string.You will have to retrieve the environment variable, using
os.environ, and then concatenate it into the string, e.g.If your input string is coming from a file, then you can evaluate the environment variables using
os.path.expandvars():If you need to account for escaped variables in the string, you can send the string off to
echoin the shell usingsubprocess.run()withshellset toTrue.This version will work in all three cases in your situation. It works regardless of how the variable is escape, e.g. slash-escaped or using quotes.
WARNING:
Setting
shelltoTrueis dangerous. Only do this if the input string is trusted.For example, if the string was
"My name is $USER; rm file", then the filefilewould be removed.