我有一个这样的config_file.yml文件:
sample:
sql: "select * from dbname.tableName where sampleDate>='2018-07-20';"
config: {'hosts': [!!python/tuple ['192.162.0.10', 3001]]}
sample2:
sql: "select * from dbname.tableName where sampleDate<='2016-05-25';"
config: {'hosts': [!!python/tuple ['190.160.0.10', 3002]]}
我的python代码是:
data_config = yaml.load(config_file)
for dataset, config in data_config.items():
args = [config]
cmd = ['./execute_something.sh']
cmd.extend(args)
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True).communicate()
execute_something.sh:
#!/bin/bash
echo $1
data_config=$1
echo $data_config
因此,基本上我想将整个字符串{'sql': "select * from dbname.tableName where sampleDate>='2018-07-20';", config: {'hosts': [!!python/tuple ['190.160.0.10', 3002]]}}
作为参数传递给Shell脚本。
问题:
1)select *
最终列出了当前目录中的所有文件,而不是完全以字符串形式传递
2)即使我传递了一个简单的字符串,说args="hi"
仍然无效!
我不明白我在这里想念的是什么。请帮助。 谢谢!
答案 0 :(得分:1)
shell=True
。data_config = yaml.load(config_file)
for dataset, config in data_config.items():
cmd = ['./execute_something.sh', str(config)]
p = subprocess.Popen(cmd, stdout=subprocess.PIPE).communicate()
运行shell=True
时,您会将sh -c
放在文字参数列表的前面。在这种情况下,将执行以下操作(将转义添加为单引号文字):
sh -c './execute_something.sh' '{'"'"'sql'"'"': "select * from dbname.tableName where sampleDate>='"'"'2018-07-20'"'"';", config: {'"'"'hosts'"'"': [!!python/tuple ['"'"'190.160.0.10'"'"', 3002]]}}'
那是行不通的。如果愿意,可以在shell中手动尝试。 为什么?因为以{
开头的参数不会传递给./execute_something.sh
,而是传递给执行sh -c
的shell。
如果您真的坚持保留shell=True
,什么会起作用?比较以下内容:
sh -c './execute_something.sh "$@"' _ '{'"'"'sql'"'"': "select * from dbname.tableName where sampleDate>='"'"'2018-07-20'"'"';", config: {'"'"'hosts'"'"': [!!python/tuple ['"'"'190.160.0.10'"'"', 3002]]}}'
这里,-c
之后的参数是一个shell脚本,它查看其参数,并将这些参数传递给execute_something.sh
。