【问题标题】:Passing multiple variables from python script to shell script将多个变量从 python 脚本传递到 shell 脚本
【发布时间】:2016-05-26 23:06:54
【问题描述】:

我试图通过将 python 变量导出到 shell 脚本而不是直接从用户那里读取它们来从 python 运行 shell 脚本。关于passing array values as variable to shell script 的问题早先已成功回答,并帮助我将数组中的值作为输入变量传递给shell 脚本。我想从以下python脚本中导出多个变量,例如FLUIDTTYPEFLIBRARY

FLUID="MDM"
TTYPE=0
FLIBRARY="RefProp"
HSPACE=[0.01, 0.009, 0.008, 0.007]
subprocess.call(['./testfile1'] + [str(n) for n in HSPACE])

到以下名为 testfile1 的 shell 脚本:

#!/bin/bash
echo "$FLUID, $FLIBRARY" | ./vls.exe
for i; do
awk 'NR==8 {$1="     " a }1'  a=$i  spacingcontrol.vls > tmp.vls && mv tmp.vls spacingcontrol.vls 
awk 'NR==8 {$2="  " b "      "}1'     b=$i spacingcontrol.vls > tmp.vls && mv tmp.vls spacingcontrol.vls 
done

【问题讨论】:

  • 您知道如何做到这一点吗?你有没有写过代码来探索这个想法?
  • @TomKarzes 在您在上面看到的那段 python 代码中,我能够将 HSPACE 作为变量发送到 shell 脚本,但是,我不知道如何同时发送多个变量。
  • @Arya, ...当您在另一个问题中问到如何使用多个变量时,我以为您的意思是多个 数组。如果只有一个数组,则更容易变得微不足道 - 您只需将其他值放在首位,然后使用 shift 将它们从列表中弹出。

标签: python shell variables


【解决方案1】:

您可以在 Python 脚本中将它们设置为环境变量:

import os 
import subprocess

os.environ['FLUID'] ="MDM"
os.environ['TTYPE'] = str(0)
os.environ['FLIBRARY'] = "RefProp"
HSPACE=[0.01, 0.009, 0.008, 0.007]
subprocess.call(['./testfile1'] + [str(n) for n in HSPACE])

【讨论】:

  • 使用此方法成功导出变量,但是如何在shell脚本中调用它们?
  • @Arya、$FLUID$TTYPE$FLIBRARY;在另一个问题中您不能这样做的唯一原因是您需要一个数组。如果这不能完全按原样工作,请参阅 envsubprocess.call 的参数。
  • @Arya, ...顺便说一句,subprocess.Popen 还有一个用于环境的单独参数,因此可以通过这种方式传递此类参数。
  • (现在,顺便说一句,这些名称不应该全部大写——参见pubs.opengroup.org/onlinepubs/009695399/basedefs/… POSIX 标准的第四段)
【解决方案2】:

您可以选择将变量作为参数传递吗?

subprocess.call(['./testfile1 %s %s' % (FLUID, FLIBRARY)] + [str(n) for n in HSPACE])

在 bash 脚本中

#!/bin/bash
FLUID=$1
FLIBRARY=$2
echo "$FLUID, $FLIBRARY" | ./vls.exe

【讨论】:

  • %d 需要一个整数才能工作,并且不能与字符串一起工作,如果我没记错的话?
  • @Arya 对不起,这就是我要写的。我的错。编辑答案来代表这个
  • 我试过这个方法,我得到以下错误:OSError: [Errno 2] No such file or directory
  • 使用字符串替换将您的数组放在命令行上是导致 shell 注入漏洞的秘诀。而是传递一个文字 argv 数组。
  • ...另外,这根本不起作用,因为它传递了第一个需要 shell 来解析它的参数,但没有使用shell=True。如果您尝试通过添加 shell=True 来修复它,那么 HSPACE 条目将不再出现在 argv 上。
【解决方案3】:

通过环境

#!/usr/bin/env python
import subprocess

FLUID="MDM"
TTYPE=0
FLIBRARY="RefProp"
HSPACE=[0.01, 0.009, 0.008, 0.007]
subprocess.call(['./testfile1'] + [str(n) for n in HSPACE],
  env={'fluid': FLUID, 'ttype': str(TTYPE), 'flibrary': FLIBRARY})

...然后,在外壳中:

#!/bin/bash
hspace=( "$@" )
declare -p fluid ttype flibrary hspace # print values

...输出为:

declare -x fluid="MDM"
declare -x ttype="0"
declare -x flibrary="RefProp"
declare -a hspace='([0]="0.01" [1]="0.009" [2]="0.008" [3]="0.007")'

在命令行上

另一种方法是使用位置参数。

#!/usr/bin/env python
import subprocess

FLUID="MDM"
TTYPE=0
FLIBRARY="RefProp"
HSPACE=[0.01, 0.009, 0.008, 0.007]

subprocess.call(['./testfile1', str(FLUID), str(TTYPE), str(FLIBRARY)] + [str(n) for n in HSPACE])

...并且,在外壳中:

#!/bin/bash
fluid=$1; shift
ttype=$2; shift
flibrary=$3; shift
hspace=( "$@" )
declare -p fluid ttype flibrary hspace # print values

...输出为:

declare -- fluid="MDM"
declare -- ttype="RefProp"
declare -- flibrary="0.009"
declare -a hspace='([0]="0.01" [1]="0.009" [2]="0.008" [3]="0.007")'

注意:

  • 使用awk -v var="$val" 是将变量值从bash 传递到awk 的正确方法;其他方法可能存在代码注入漏洞。
  • 对用户定义的环境变量使用小写名称符合 POSIX 约定以避免命名空间冲突;见relevant spec

【讨论】:

  • 感谢您对命名空间冲突的见解,请记住!
  • 我尝试运行这两种方法并最终得到代码无法执行 vls.exe 的错误。但是,当我从终端独立运行 shell 脚本并将 FLUID、FLIBRARY 等作为用户输入时,它可以正常工作。
  • @Arya,在尝试这些方法时,您是否使用了我的答案中给出的 exact 代码?我可以在这里测试代码工作;我无法测试第 3 方改编。
  • @Arya, ...我已将代码示例更新为完全独立,因此您可以将它们直接复制并粘贴到其他空文件中并让它们工作 - 现在我显示每个的输出。
  • @Arya, ...我可以看到事情被破坏的唯一地方是如果你在 Windows 上运行 - 传递 env=... 将覆盖默认环境变量,如 PATH 那里(以及方式argv 的工作方式也不同——它是一个全方位的螺旋平台)。但是您的问题没有标记 for Windows...