Bash脚本由Java进程调用,如下所示:
./spark_submit.sh ${SPARK_HOME}/bin/spark-submit --master yarn --deploy-mode cluster --conf spark.yarn.historyServer.address=${hadoopconf-yarn.resourcemanager.hostname}:18080
我必须对输入参数运行操作,所以我检查每个参数并重建原始输入。
我通过访问$ 1值然后移位逐个获取参数。
我找不到阻止bash解决的方法
$ {} SPARK_HOME /斌/火花提交
至
/斌/火花提交
和
$ {hadoopconf,yarn.resourcemanager.hostname}
至
yarn.resourcemanager.hostname
Java进程没有选择以不同的方式传递参数,例如使用转义斜杠。
有任何想法吗?
如果有一个shell是shell脚本的父进程,在该脚本启动之前将一个字符串分解为一个参数列表(并在它们上运行扩展),那么你只会遇到这个问题。当使用编程语言与C system()
函数类似时,通常会发生这种情况,该函数接受单个字符串并将其作为参数传递给sh -c '...'
。
并且因为该过程在脚本启动之前发生,所以您无法从脚本内部修复它。
将文字参数列表传递到JVM中,并且您没有遇到该问题:
List<Array> args = Arrays.asList(
"./spark_submit.sh",
"${SPARK_HOME}/bin/spark-submit",
"--master", "yarn",
"--deploy-mode", "cluster",
"--conf", "spark.yarn.historyServer.address=${hadoopconf-yarn.resourcemanager.hostname}:18080");
ProcessBuilder p = new ProcessBuilder(args);
p.start();
也就是说,你的脚本期望这种形式的参数是一个“代码味道”,它可能有serious security vulnerabilities如何处理参数;注意传入的值是经过审计/审查/控制的,或者(更好!)有人重写它以避免使用eval
。
用'(单引号)传递它。单引号可防止扩展。
就是这样的:
./spark_submit.sh '${SPARK_HOME}/bin/spark-submit' --master yarn --deploy-mode cluster --conf spark.yarn.historyServer.address='${hadoopconf-yarn.resourcemanager.hostname}:18080'