1

我想将字符串拆分为命令行参数,就像 shlex.split 一样。但是,shlex 似乎并没有转换环境变量(例如$USER),并且输出使得无法知道环境变量是否被转义:

>>> 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']

有没有办法做到这一点?(希望没有重新实现整个事情)

另外,为什么 shlex.split 首先默认不这样做?

如果重要的话,我使用的是 Python 3.6.8。

4

1 回答 1

1

传入的参数shlex.split()是一个字符串

您必须使用 检索环境变量,os.environ然后将其连接到字符串中,例如

import shlex
import os
print(shlex.split(f"My name is {os.environ['USER']}"))
# ['My', 'name', 'is', 'Alice']

如果您的输入字符串来自文件,那么您可以使用以下方法评估环境变量os.path.expandvars()

import shlex
import os
print(shlex.split(os.path.expandvars("My name is $USER")))
# ['My', 'name', 'is', 'Alice']

如果您需要考虑字符串中的转义变量,您可以使用with set to将字符串发送到echoshell中。subprocess.run()shellTrue

在您的情况下,此版本适用于所有三种情况。无论变量如何转义,例如斜杠转义或使用引号,它都可以工作。

import shlex
import subprocess

strings = [
    "My name is Alice",
    "My name is '$USER'",
    "My name is \$USER",
    "My name is $USER"
]

for s in strings:
    split = subprocess.run(f'echo {s}', shell=True, stdout=subprocess.PIPE)
    print(shlex.split(split.stdout.decode('utf-8')))
# ['My', 'name', 'is', 'Alice']
# ['My', 'name', 'is', '$USER']
# ['My', 'name', 'is', '$USER']
# ['My', 'name', 'is', 'Alice']

警告:

设置shellTrue危险。仅当输入字符串受信任时才执行此操作。

例如,如果字符串是"My name is $USER; rm file",则文件file将被删除。

于 2021-01-13T11:58:43.050 回答