Shell变量传递带空格的spark-submit命令行参数解析异常如何解决
问题原因
Shell解析普通字符串变量时,仅会按内部字段分隔符(IFS,默认包含空格、制表符、换行符)拆分内容,你写在变量里的双引号仅会被识别为普通文本字符,不会作为参数边界的包裹符号。因此query "Id==1 and customer==2"这个字符串会被拆分为query、"Id==1、and、customer==2"四个片段,传入程序后就会出现参数拆分错误的问题。
另外你提供的params.sh存在笔误:定义的查询条件变量名为QUERYCOND,但ARGS赋值时用了未定义的$CUSTOM,也会导致参数取值错误。
解决方案
优先使用Shell数组存储多参数,数组天然支持带空格的元素,不会出现非预期的拆分问题,修改步骤如下:
- 修改
params.sh,将ARGS改为数组类型,同时修正笔误:
MODE="query" QUERYCOND="Id==1 and customer==2" PACKAGE="com.etl" CLASS="ExecSparkETL" DRIVER_CLASS_PATH="/home/jars/ojdbc8.jar" JARS="/home/jars/ojdbc8.jar" JAR="/home/jars/etl-scala_2.11-1.0.0.jar" # 数组的每个元素对应一个传入jar包的参数,无需额外加转义双引号 ARGS=("$MODE" "$QUERYCOND")
- 修改
exec.sh中ARGS的调用方式,使用"${ARGS[@]}"格式展开数组,保留每个参数的边界:
source params.sh spark2-submit \ --class ${PACKAGE}.${CLASS} \ --queue root.me \ --deploy-mode client \ --master yarn \ --driver-class-path $DRIVER_CLASS_PATH \ --jars $JARS \ --conf spark.network.timeout=1200000 \ $JAR \ "${ARGS[@]}"
方案说明
"${ARGS[@]}"展开后等价于直接在命令行写"query" "Id==1 and customer==2",和你手动写参数的效果完全一致,Shell会正确识别为两个独立参数,空格不会被拆分。如果后续需要新增参数,直接往ARGS数组追加元素即可,例如ARGS=("$MODE" "$QUERYCOND" "第三个带空格的参数")。
如果不想使用数组,也可以用eval强制重新解析命令,但该方法存在特殊字符注入风险,不推荐使用:
# 不推荐的备选方案,存在安全风险 eval spark2-submit \ --class ${PACKAGE}.${CLASS} \ --queue root.me \ --deploy-mode client \ --master yarn \ --driver-class-path $DRIVER_CLASS_PATH \ --jars $JARS \ --conf spark.network.timeout=1200000 \ $JAR \ $ARGS
内容的提问来源于stack exchange,提问作者SteveTR
相关产品推荐
相关产品推荐

