shell执行scala脚本

来源:互联网 发布:昆明郊野公园知乎 编辑:程序博客网 时间:2024/05/22 09:23

新建一个helloworld.sh如下:

[plain] view plain copy
  1. #!/bin/sh  
  2. exec scala "$0" "$@"  
  3. !#  
  4.   
  5. case class Person(name:String)  
  6.   
  7. object HelloWorld {  
  8.         def main(args:Array[String]){  
  9.                 require(args.length==1)  
  10.                 val al = Person(args(0))  
  11.                 println(al)  
  12.         }  
  13. }  
  14.   
  15. HelloWorld.main(args)  



println(al) }}HelloWorld.main(args)

chmod 777 helloworld.sh之后,就能通过./helloworld.sh xiaojun来执行了,输出为:

Persion(xiaojun)

shell脚本里执行scala脚本的黑科技升级版:

[plain] view plain copy
  1. #!/bin/sh  
  2. xmlpath="/data/hupu/dace/streaming/$1"  
  3. export HADOOP_USER_NAME=hdfs  
  4. xmlString=$(hadoop fs -cat "$xmlpath")  
  5. exec scala "$0" "$xmlString" "$xmlpath"  
  6. !#  
  7.   
  8. import scala.xml.XML  
  9. import scala.sys.process._  
  10. object StreamingSubmit {  
  11.         def main(args:Array[String]){  
  12.                 require(args.length==2)  
  13.                 val config = XML.loadString(args(0))  
  14.                 val configFile = args(1)  
  15.                 val submitArgs = (config \ "submit-args")  
  16.                 val numExecutors = (submitArgs \ "@num-executors").text  
  17.                 val driverMemory = (submitArgs \ "@driver-memory").text  
  18.                 val executorMemory = (submitArgs \ "@executor-memory").text  
  19.                 val executorCores = (submitArgs \ "@executor-cores").text  
  20.                 val memoryFraction = (submitArgs \ "@memoryFraction").text  
  21.                 println(numExecutors,driverMemory,executorMemory,executorCores,memoryFraction)  
  22.                 val assemblyJar = "spark-assembly-1.4.0-hadoop2.5.0-cdh5.3.0.jar"  
  23.                 val submitShell = s"""/opt/spark/bin/spark-submit --driver-class-path /opt/spark/lib/$assemblyJar:/opt/spark/lib/dace-streaming.jar --jars /opt/spark/lib/dace-streaming.jar,/opt/spark/lib/HiveUDF-1.0-jar-with-dependencies.jar  --class com.hupu.dace.spark.streaming.framework.StreamingRunner     --master yarn-cluster --num-executors $numExecutors     --driver-memory $driverMemory     --executor-memory $executorMemory     --executor-cores $executorCores  --conf spark.storage.memoryFraction=$memoryFraction --conf spark.sql.hive.metastore.jars=/opt/spark/lib/$assemblyJar   /opt/spark/lib/dace-streaming.jar  $configFile"""  
  24.                 println(submitShell)  
  25.                 submitShell.!!  
  26.   
  27.         }  
  28.   
  29.   
  30. }  
  31.   
  32. StreamingSubmit.main(args)  


本来是想用shell去解析xml文件然后拼接成一个完整的提交spark-submit指令,百度了一下shell解析XML,瞬间放弃了。然后想到了以前用过的shell执行scala脚本的黑科技,果然方便多了。

上面的代码还是蛮有意思的,先从 shell脚本启动执行scala脚本,在scala代码里又引入了

[plain] view plain copy
  1. scala.sys.process._  
又通过.!!来执行shell指令。我自己写出来也是醉了。

不过其中遇到了一个问题没解决,就是没法拼接--driver-java-options参数,比如我要设置--driver-java-options "-XX:PermSize=128M -XX:MaxPermSize=256M" ,第二个-XX前面那个空格会被隔断看成另外一个参数。而直接在shell命令行是可以这样写传入java options的。试了很久都没试出来怎么写。还好是通过yarn-cluster方式执行,于是把这个参数配置到spark-defaults.conf里面去了,如果是yarn-client模式的话driver早就启动了,只能在命令行设置--driver-java-options参数才能使driver jvm参数生效,否则太晚了。


demo2:

[java] view plain copy
  1. #!/bin/sh  
  2. hdfs_path="$1"  
  3. export HADOOP_USER_NAME=hdfs  
  4. interval="$2"  
  5. exec scala "$0" "$hdfs_path" "$interval"  
  6. !#  
  7.   
  8. import java.util.Date  
  9. import scala.sys.process._  
  10.   
  11. /** 
  12.  * Created by xiaoj on 2016/7/27. 
  13.  */  
  14. object MyApp {  
  15.   def main(args: Array[String]) {  
  16.     require(args.length == 2)  
  17.     val Array(path, interval) = args  
  18.     println(path)  
  19.     var last_time = ""  
  20.     val shell = s"""hadoop fs -stat $path"""  
  21.     val subshell="""./subshell.sh"""  
  22.     println("exec shell :" + shell)  
  23.     while (true) {  
  24.       val current_time = (shell !!).trim  
  25.       if (current_time != last_time) {  
  26.         //exec shell  
  27.   
  28.         println(s"======exec sync shell,current time:${new Date()},last file time=$last_time,current file time:$current_time========")  
  29.         val result = subshell.!!  
  30.         println(result)  
  31.         //subshell.!!  
  32.         last_time = current_time  
  33.       } else {  
  34.         println(s"======no change,current time:${new Date()},last file time=$last_time,current file time:$current_time========")  
  35.       }  
  36.       Thread.sleep(interval.toLong)  
  37.     }  
  38.   }  
  39. }  
  40.   
  41. MyApp.main(args)