将Groovy脚本的输出用作另一个Groovy脚本的输入

4
我很抱歉,我是一个新手,对groovy不太熟悉。我的问题是我有三个不同功能的groovy脚本,我需要从我的主groovy脚本中调用它们,使用脚本1的输出作为脚本2的输入,脚本2的输出作为脚本3的输入。
我尝试了以下代码:
script = new GroovyShell(binding)
script.run(new File("script1.groovy"), "--p",  "$var" ) | script.run(new File("script2.groovy"), "<",  "$var" )

当我运行上述代码时,第一个脚本成功运行,但第二个根本没有运行。
脚本1使用“--p”、“$var”代码以int作为参数。在主脚本中成功运行:script.run(new File("script1.groovy"), "--p", "$var") - 脚本1的输出是一个xml文件。
当我在主groovy脚本中单独运行 script.run(new File("script2.groovy"), "<", "$var") 时,什么也不会发生,系统会挂起。
我可以使用 groovy script2.groovy < input_file 命令从命令行运行脚本2,并且它可以正常工作。
非常感谢您的帮助。
2个回答

1

当您从命令行运行脚本时,无法将<作为参数传递给脚本,因为重定向由Shell处理...

将脚本的输出重定向到其他脚本通常非常困难,基本上依赖于您在每个脚本的持续时间内更改System.out(并希望JVM中没有其他内容打印并破坏您的数据)

最好使用以下Java进程:

假设有这3个脚本:

script1.groovy

// For each argument
args.each {
  // Wrap it in xml and write it out
  println "<woo>$it</woo>"
}

linelength.groovy

// read input
System.in.eachLine { line ->
  // Write out the number of chars in each line
  println line.length()
}

pretty.groovy

// For each line print out a nice report
int index = 1
System.in.eachLine { line ->
  println "Line $index contains $line chars (including the <woo></woo> bit)"
  index++
}

我们可以编写类似以下代码,以便逐个运行新的 Groovy 进程,并将输出管道传递到彼此之间(使用 Process 上重载的 or 运算符):
def s1 = 'groovy script1.groovy arg1 andarg2'.execute()
def s2 = 'groovy linelength.groovy'.execute()
def s3 = 'groovy pretty.groovy'.execute()

// pipe the output of process1 to process2, and the output
// of process2 to process3
s1 | s2 | s3

s3.waitForProcessOutput( System.out, System.err )

打印出以下内容:

Line 1 contains 15 chars (including the <woo></woo> bit)
Line 2 contains 18 chars (including the <woo></woo> bit)

谢谢您提供的解决方案,我可以问两个与解决方案相关的问题吗? - Alan
当运行第一个脚本时,参数将来自列表,因此它们每次都会更改。在您的解决方案中,是否可以将参数指定为$arg,或者该语法在解决方案中使用是非法的? - Alan
2- 当使用脚本1的输出作为脚本2的输入时,脚本2被设计成用户可以指定输入。因此,在从命令行调用脚本时,要指定输入文件,您将使用script2 < inputFile;如果传递参数,则使用script2 --p arg(arg将是一个整数)。因此,在将一个脚本的输出作为另一个脚本的输入进行管道传输时,是否需要标志或者管道是否覆盖了标志的需要? - Alan
对于1:def s1 = "groovy script1.groovy ${args.join( ' ' )}".execute()对于2:应该可以直接使用(我想) - tim_yates

0
//store standard I/O
PrintStream systemOut = System.out
InputStream systemIn = System.in
//Buffer for exchanging data between scripts
ByteArrayOutputStream buffer = new ByteArrayOutputStream()
PrintStream out = new PrintStream(buffer)
//Redirecting "out" of 1st stream to buffer
System.out = out
//RUN 1st script
evaluate("println 'hello'")
out.flush()
//Redirecting buffer to "in" of 2nd script
System.in = new ByteArrayInputStream(buffer.toByteArray())
//set standard "out"
System.out = systemOut
//RUN 2nd script
evaluate("println 'message from the first script: ' + new Scanner(System.in).next()")
//set standard "in"
System.in = systemIn

结果是:'第一个脚本的消息:你好'


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接