我的python文件有以下两个变量:
week_date = "01/03/16-01/09/16"
cust_id = "12345"
Run Code Online (Sandbox Code Playgroud)
我如何将其读入一个接受这两个变量的shell脚本?
我当前的shell脚本需要手动编辑"dt"和"id".我想将python变量读入shell脚本,这样我就可以编辑我的python参数文件而不是那么多文件.
shell文件:
#!/bin/sh
dt="01/03/16-01/09/16"
cust_id="12345"
Run Code Online (Sandbox Code Playgroud)
在一个新的python文件中,我可以导入参数python文件.
考虑类似于以下内容:
#!/bin/bash
# ^^^^ NOT /bin/sh, which doesn't have process substitution available.
python_script='
import sys
d = {} # create a context for variables
exec(open(sys.argv[1], "r").read()) in d # execute the Python code in that context
for k in sys.argv[2:]:
print "%s\0" % str(d[k]).split("\0")[0] # ...and extract your strings NUL-delimited
'
read_python_vars() {
local python_file=$1; shift
local varname
for varname; do
IFS= read -r -d '' "${varname#*:}"
done < <(python -c "$python_script" "$python_file" "${@%%:*}")
}
Run Code Online (Sandbox Code Playgroud)
然后您可以将其用作:
read_python_vars config.py week_date:dt cust_id:id
echo "Customer id is $id; date range is $dt"
Run Code Online (Sandbox Code Playgroud)
...或者,如果您不想在阅读时重命名变量,只需:
read_python_vars config.py week_date cust_id
echo "Customer id is $cust_id; date range is $week_date"
Run Code Online (Sandbox Code Playgroud)
好处:
sed处理原始和常规字符串,以及单引号和三引号,而不是将它变成毛球!)或类似的方法使用来自Python子进程的换行符分隔的输出,这将正确处理任何对象,该对象为str()您的shell脚本可以使用没有NUL字符的表示.通过Python解释器运行内容也意味着您可以以编程方式确定值 - 例如,您可能有一些Python代码要求您的版本控制系统提供相关内容的最后更改日期.
想想这样的场景:
start_date = '01/03/16'
end_date = '01/09/16'
week_date = '%s-%s' % (start_date, end_date)
Run Code Online (Sandbox Code Playgroud)
...使用Python解释器来解析Python意味着您不会限制人们将来如何更新/修改Python配置文件.
现在,让我们来谈谈:
import在Python中选择文件作为模块一样).不要使用它从您不信任其内容的文件中提取配置.str()表示包含NUL 的对象溢出到其他赋值中,此代码在其第一个NUL处终止字符串.现在,我们来谈谈实现细节.
${@%%:*}是一个扩展,$@它修剪:了每个参数中的第一个内容之后的所有内容,因此只将Python变量名称传递给解释器.类似地,${varname#*:}是一个扩展,它修改一切,包括:传递给变量名的第一个read.请参阅参数扩展的bash-hackers页面.<(python ...)是进程替换语法:<(...)表达式求值为一个文件名,当读取该文件名时,将提供该命令的输出.使用< <(...)该文件的重定向输出,从而使用该命令(第一个<是重定向,而第二个是<(开始进程替换的令牌的一部分).使用这种形式将输出输出到while read循环中避免了BashFAQ#24中提到的错误("我在一个循环中设置变量在管道中.为什么它们在循环终止后消失?或者,为什么我不能管道数据读取?").该IFS= read -r -d ''构造具有一系列组件,每个组件使得行为read更加真实于原始内容:
IFS命令的持续时间可防止从变量内容的末尾修剪空白.-r防止文字反斜杠被read自己消耗而不是在输出中表示.-d ''将空字符串的第一个字符设置为''记录分隔符.由于C字符串是NUL终止的,而shell使用C字符串,因此该字符是NUL.这可确保变量的内容可以包含任何非NUL值,包括文字换行符.有关从字符串读取面向记录的数据的过程的更多信息,请参阅BashFAQ#001("如何逐行(和/或逐字段)读取文件(数据流,变量)?")在bash中.
| 归档时间: |
|
| 查看次数: |
4688 次 |
| 最近记录: |