Spark场景下如何从shell脚本传递含双大括号的参数到Python脚本
问题原因
这个问题是Shell的**大括号扩展(brace expansion)**特性导致的,和Spark、Python argparse模块无关:Shell解析双引号包裹的字符串时,会自动识别连续大括号做扩展处理,导致你传递的参数末尾的}}被截断,最终Python拿到的参数少了一个右大括号。
解决方案
下面是3种常用的可行方案,按需选择即可:
方案1:用单引号包裹参数字符串
Shell中单引号会禁用所有变量解析、特殊字符扩展逻辑,单引号内的内容会原样传递给目标程序。修改b.sh的提交代码如下:
spark_submit=/usr/custom/spark/bin/spark-submit $spark_submit \ --name "test" \ # 外层用单引号包裹参数,内容原样传递 a.py --param '{"a":{"b":2}}'
如果你参数内必须用单引号,可以把内层单引号做转义处理:
'{"a":'"'"'b'"'"':2}'或者用'{"a":'\''b'\'':2}'格式。
方案2:双引号内转义所有大括号
如果必须用双引号包裹参数(比如参数里要插入Shell变量),可以给所有{、}字符前加反斜杠\转义,让Shell跳过对这些大括号的扩展解析:
spark_submit=/usr/custom/spark/bin/spark-submit $spark_submit \ --name "test" \ a.py --param "{'a':\{'b':2\}\}"
方案3:预先把参数存入变量
先把参数值用单引号赋值给变量,传递的时候用双引号包裹变量即可,写法更易读:
spark_submit=/usr/custom/spark/bin/spark-submit # 单引号赋值,内容原样保存 param_val='{"a":{"b":2}}' $spark_submit \ --name "test" \ a.py --param "$param_val"
验证效果
修改后重新运行b.sh,a.py输出结果为Namespace(param="{'a':{'b':2}}"),符合预期。
内容的提问来源于stack exchange,提问作者zhangboyu
相关产品推荐
相关产品推荐

