我试图让Groovy脚本读取标准输入,所以我可以用带有heredoc的Bash脚本调用它,但是我得到java.lang.NullPointerException: Cannot invoke method readLine() on null object
例外。
这是一个简洁的Groovy脚本echo.groovy
:
#!/usr/bin/env groovy
for (;;)
{
String line = System.console().readLine()
if (line == null)
break
println(">>> $line")
}
这里是等效的Ruby脚本echo.rb
:
#!/usr/bin/env ruby
ARGF.each do |line|
puts ">>> #{line}"
end
如果我从Bash shell调用它们,一切都按预期工作:
$ ./echo.rb
one
>>> one
two
>>> two
three
>>> three
^C
$ ./echo.groovy
one
>>> one
two
>>> two
three
>>> three
^C
这是使用heredocs的Bash脚本heredoc.sh
:
echo 'Calling echo.rb'
./echo.rb <<EOF
one
two
three
EOF
echo 'Calling echo.groovy'
./echo.groovy <<EOF
one
two
three
EOF
当我运行它时会发生这种情况:
$ ./heredoc.sh
Calling echo.rb
>>> one
>>> two
>>> three
Calling echo.groovy
Caught: java.lang.NullPointerException: Cannot invoke method readLine() on null object
java.lang.NullPointerException: Cannot invoke method readLine() on null object
at echo.run(echo.groovy:4)
有什么想法吗?
更新
在Etan的建议中,我将echo.groovy
更改为以下内容:
#!/usr/bin/env groovy
Reader reader = new BufferedReader(new InputStreamReader(System.in))
for (;;)
{
String line = reader.readLine()
if (line == null)
break
println(">>> $line")
}
它现在适用于heredocs:
$ ./heredoc.sh
Calling echo.rb
>>> one
>>> two
>>> three
Calling echo.groovy
>>> one
>>> two
>>> three
谢谢Etan。如果您想发布正式答案,我会提出建议。
答案 0 :(得分:1)
正如Etan所说,你需要阅读System.in
我认为这会得到你的回应
#!/usr/bin/env groovy
System.in.withReader { r ->
r.eachLine { line ->
println ">>> $line"
}
}
认为它与Ruby版本不完全相同,因为ARGF
将返回参数(如果有的话)
答案 1 :(得分:1)
作为Etan答案的替代方案,Groovier方法是withReader
方法,后者处理读取器的清理,以及BufferedReader的eachLine方法,它处理无限循环。
#!/usr/bin/env groovy
System.in.withReader { console ->
console.eachLine { line ->
println ">>> $line"
}
}