【问题标题】:Run scala script from shell script从 shell 脚本运行 scala 脚本
【发布时间】:2017-01-19 10:41:55
【问题描述】:

我有一个包含 Scala 类/对象和脚本的 Scala 项目。我正在尝试从命令行运行脚本(使用类/对象执行各种操作)。我希望这样做的方法是创建一个外壳程序,该外壳程序将作为脚本名称以及脚本本身采用的参数作为参数传递。

我的文件夹结构如下:

runner.sh -> script I am trying to implement to run the Scala scripts
bin/ -> script I am trying to implement to run the Scala scripts
lib/ -> -> rest of scala project, packed as multiple jars 

我目前正在 shell 脚本中创建一个变量 LIB_CLASSPATH,其中包含 lib/ 文件夹的内容,我正在尝试按如下方式运行我的脚本:

java -cp $LIB_CLASSPATH ./bin/<name_of_script.scala> <parameters of the script>

我总是返回同样的错误:

Could not find or load main class: ..lib/<name of jar> 
-- <name of jar> is actually the first jar in the lib/ folder

我可以使用一些指导:)

谢谢

【问题讨论】:

  • 您似乎正在向java 传递Scala 源代码的脚本。它不知道如何处理它。要么使用scala 而不是java,要么先编译你的脚本。

标签: scala shell classpath


【解决方案1】:

你可以使用Ammonite(作者@lihaoyi)。

它结合了更好的 Scala REPL、Shell、OPs 库和脚本运行器。 在此处查看文档 - https://ammonite.io/

10 分钟的演讲展示了如何更好地编写脚本和 shell - https://www.youtube.com/watch?v=wk2-ZsQU358

我认为这也是一个很好的起点。谈话是我发表的:)

【讨论】:

  • 很遗憾不能使用 Ammonite
  • @AdrianDanielCulea 为什么?
  • 未经公司批准
  • 上述菊石链接不再有效
【解决方案2】:

我会推荐使用 sbt 原生打包器。见:

https://github.com/sbt/sbt-native-packager

你将这一行添加到 build.sbt:

enablePlugins(JavaAppPackaging)

并定义一个主类:

mainClass in Compile := Some("org.shapelogic.sc.javafx.ViewGui")

运行:

sbt stage

它会在这样的地方创建启动脚本:

target/universal/stage/bin/shapelogic

这是我如何使用脚本的示例:

target/universal/stage/bin/shapelogic -- -i image/440px-Lenna.png 

如果你想运行另一个类,你可以这样做:

target/universal/stage/bin/shapelogic -main "org.shapelogic.sc.script.Threshold" -- i image/440px-Lenna.png 

【讨论】:

  • 很遗憾,我不能使用 sbt
  • 您可以尝试查看 sbt native packager 构建的启动脚本并制作一个简化版本。
  • sbt 本机打包程序创建一个小 bash 脚本来声明所需的变量: 他们为 app_classpath 调用您的 LIB_CLASSPATH 这是开始:declare -r app_classpath="$lib_dir/org.shapelogic.sc。 shapelogic-0.4.1.jar:$lib_dir/org.scala-lang.scala-library-2.11.8.jar:...
  • 我用整个 bash 启动脚本创建了一个 Gist:gist.github.com/sami-badawi/82c303502d761db12aec11bb76d1e67d
【解决方案3】:

这是一个可以执行您想要的操作的脚本。它基于我使用的一个脚本,但为了清晰起见被剥离:

#!/bin/bash

# copies of or symlinks to all required jar files
# must be in one of the directories referenced by CP

if [ $# -eq 0 ]; then
  echo "usage: ${0##*} <scala-script-path>" 1>&2
  exit 1
fi

REQUIRED_JAR_DIRECTORIES=(
"/usr/local/olib/*"
"/usr/local/jlib/*"
)
CP=$(echo "${REQUIRED_JAR_DIRECTORIES[@]}" | tr ' ' ':')
case `uname` in
CYGWIN*)
  CP=`cygpath -p -w "$CP"`
  ;;
esac
scala -deprecation -feature -classpath "$CP" "$@"

使用此脚本的最简单方法是将其放置在 PATH 中,然后将以下 hash-bang 行添加到 scala 脚本的顶部。假设您将此脚本称为“scalaRunner”,这是一个独立的工作 scala 脚本:

#!/usr/bin/env scalaRunner

println("Hello World!")

这里稍微复杂一点:

#!/usr/bin/env scalaRunner

if( args.isEmpty ){
  printf("usage: <arg1> [<arg2> ..]\n")
  sys.exit(1)
}
for( (arg,i) <- args.zipWithIndex ){
  printf("arg %d: %s\n",i,arg)
}

如果您导入任何内容,只需确保所有必需的 jar 都在 REQUIRED_JAR_DIRECTORIES 中。

实际上,您可能需要比这个脚本更灵活的东西,尤其是在指定所需 jar 所在的位置方面。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-09-29
    • 2016-05-27
    • 2013-04-18
    • 1970-01-01
    • 1970-01-01
    • 2012-03-28
    • 2013-07-29
    相关资源
    最近更新 更多