I'm trying to make a Groovy script read standard input, so I can call it from a Bash script with a heredoc, but I get a java.lang.NullPointerException: Cannot invoke method readLine() on null object
exception.
Here's a cut-down Groovy script echo.groovy
:
#!/usr/bin/env groovy
for (;;)
{
String line = System.console().readLine()
if (line == null)
break
println(">>> $line")
}
Here's the equivalent Ruby script echo.rb
:
#!/usr/bin/env ruby
ARGF.each do |line|
puts ">>> #{line}"
end
If I call these from a Bash shell, everything works as expected:
$ ./echo.rb
one
>>> one
two
>>> two
three
>>> three
^C
$ ./echo.groovy
one
>>> one
two
>>> two
three
>>> three
^C
This is the Bash script heredoc.sh
using heredocs:
echo 'Calling echo.rb'
./echo.rb <<EOF
one
two
three
EOF
echo 'Calling echo.groovy'
./echo.groovy <<EOF
one
two
three
EOF
This is what happens when I run it:
$ ./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)
Any ideas?
UPDATE
On Etan's advice, I changed echo.groovy
to the following:
#!/usr/bin/env groovy
Reader reader = new BufferedReader(new InputStreamReader(System.in))
for (;;)
{
String line = reader.readLine()
if (line == null)
break
println(">>> $line")
}
It now works with heredocs:
$ ./heredoc.sh
Calling echo.rb
>>> one
>>> two
>>> three
Calling echo.groovy
>>> one
>>> two
>>> three
Thanks Etan. If you'd like to post a formal answer, I'll upvote it.
As Etan says, you need to read from System.in
I think this will get the response you are after
#!/usr/bin/env groovy
System.in.withReader { r ->
r.eachLine { line ->
println ">>> $line"
}
}
Thought it's not exactly the same as the Ruby version, as ARGF
will return arguments if any were passed
As an alternative to Etan's answer, a Groovier approach is the withReader
method, which handles the cleanup of the reader afterwards, and the BufferedReader's eachLine method, which handles the infinite looping.
#!/usr/bin/env groovy
System.in.withReader { console ->
console.eachLine { line ->
println ">>> $line"
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.