gpt4 book ai didi

python - 从 python 评估 "Shell command line with shell variables"或将 python 字符串评估为 shell 命令行

转载 作者:太空宇宙 更新时间:2023-11-03 20:03:35 24 4
gpt4 key购买 nike

上下文

我正在开发一个模拟集群。为了尽可能灵活(使用不同的模拟软件),我们创建了一个 python 文件来解析定义环境变量的配置文件,以及启动模拟的命令行。该命令通过 SLURM sbatch 命令(shell $COMMAND)启动

问题

从 python 中,所有环境变量都通过读取配置文件进行注册我对使用其他环境变量(显示为 shell 变量)的变量 COMMAND 有问题

例如

COMMAND = "fluent -3ddp -n$NUMPROCS -hosts=./hosts -file $JOBFILE"    
os.environ['COMMAND']=COMMAND
NUMPROCS = "32"
os.environ['NUMPROCS']=NUMPROCS
[...]
exe = Popen(['sbatch','template_document.sbatch'], stdout=PIPE, stderr=PIPE)

sbatch 将 COMMAND 分发到所有模拟节点,因为 COMMAND 是命令行

命令调用其他保存的环境。变量。 Shell 将其严格解释为文本...这使得命令行失败。它严格作为使用 $ 而非变量的字符串,例如:'flutter -3ddp -n$NUMPROCS -hosts=./hosts -file $JOBFILE'

我正在寻找的解决方案

我正在寻找一个简单的解决方案解决方案 1:使用 1 到 3 个 python 命令行来评估 COMMAND 作为 shell 命令来回显解决方案 2:使用 Shell 命令将“字符串”$COMMAND 中的变量作为变量进行计算最后从 sbatch 中启动的命令应该是

fluent -3ddp -n32 -hosts=./hosts -file /path/to/JOBFILE

最佳答案

您有几个选择:

  1. 部分或不支持 bash 的变量替换,例如实现一些 python 功能来重现 bash 的 $VARIABLE语法。

  2. 重现配置文件中支持的所有 bash 变量替换工具( $VARIABLE${VARIABLE}${VARIABLE/x/y}$(cmd) - 等等。

  3. 让 bash 来完成繁重的工作,以牺牲性能和可能的安全性为代价,具体取决于您对配置文件内容的信任。

我将在这里展示第三个,因为它是最具弹性的(同样,尽管存在安全问题)。假设您有这个配置文件 config.py :

REGULAR   =   "some-text"
EQUALS = "hello = goodbye" # trap #1: search of '='
SUBST = "decorated $REGULAR"
FANCY = "xoxo${REGULAR}xoxo"
CMDOUT = "$(date)"
BASH_A = "trap" # trap #2: avoid matching variables like BASH_ARGV
QUOTES = "'\"" # trap #3: quoting

然后你的Python程序就可以运行下面的咒语:

bash -c 'source <(sed "s/^/export /" config.py | sed "s/[[:space:]]*=[[:space:]]*/=/") && env | grep -f <(cut -d= -f1 config.py | grep -E -o "\w+" | sed "s/.*/^&=/")'

这将产生以下输出:

SUBST=decorated some-text
CMDOUT=Thu Nov 28 12:18:50 PST 2019
REGULAR=some-text
QUOTES='"
FANCY=xoxosome-textxoxo
EQUALS=hello = goodbye
BASH_A=trap

然后您可以使用 python 来读取它,但请注意引号现在已经消失,因此您必须考虑到这一点。

咒语解释:

bash -c 'source ...instructions... && env | grep ...expressions...'告诉 bash 读取并解释指令,然后 grep 表达式的环境。我们将把配置文件转换成修改 bash 环境的指令。

如果您尝试使用set而不是env ,输出将与引用不一致。使用env避免陷阱#3。

说明:我们将为表单创建说明:

export FANCY="xoxo${REGULAR}xoxo"

以便 bash 可以解释它们和 env可以阅读它们。

  • sed "s/^/export /" config.py为变量添加前缀 export
  • sed "s/[[:space:]]*=[[:space:]]*/=/"将赋值格式转换为 bash 可以读取的语法 source 。使用s/x/y/而不是s/x/y/g避免陷阱#1。
  • source <(...command...)使 bash 将命令的输出视为文件并一行一行地运行。

当然,避免这种复杂性的一种方法是让文件一开始就使用 bash 语法。如果是这种情况,我们将使用 source config.sh而不是source <(...command...) .

表达式:我们想要 grep env 的输出对于类似 ^FANCY= 的模式.

  • cut -d= -f1 config.py | grep -E -o "\w+"config.py 中查找变量名称.
  • sed "s/.*/^&=/"将变量名称变为 FANCY grep 搜索表达式,例如 ^FANCY= 。这是为了避免陷阱 #2。
  • grep -f <(...command...)获取grep将命令的输出视为每行包含一个搜索表达式的文件,在本例中为 ^FANCY= , ^CMDOUT=等等

编辑

由于您实际上只想将此环境传递给另一个 bash 命令而不是在 python 中使用它,因此您实际上可以让 python 运行此命令:

bash -c 'source <(sed "s/^/export /" config.py | sed "s/[[:space:]]*=[[:space:]]*/=/") && $COMMAND'

(假设在配置文件中指定了COMMAND)。

关于python - 从 python 评估 "Shell command line with shell variables"或将 python 字符串评估为 shell 命令行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59095318/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com