[groovy-user] How to properly escape groovy one liners for bash

1,843 views
Skip to first unread message

sieg...@heintze.com

unread,
Dec 29, 2012, 11:09:53 PM12/29/12
to us...@groovy.codehaus.org

I want to execute some one liners with the groovy programming language and I'm having trouble escaping the special characters to accommodate bash.


Here is one of the lines that is giving me trouble:


Code:
groovy -e "(new XmlParser().parse('languages.xml')).each{ println \"${it.@name} authored by ${it.author[0].text()}\" } "

I've tried putting single backslashes in front of the $'s and double and nothing seems to work. I get this error:


Code:
./UsingXMLParser.bash: line 50: (new XmlParser().parse('languages.xml')).each{ println "\\${it.@name} authored by \\${it.author[0].text()}" } : bad substitution

When I run the statements directly in the groovy console, they execute so I have the basic syntax correct and the problem is just keeping bash happy.


Thanks
Siegfried
--------------------------------------------------------------------- To unsubscribe from this list, please visit: http://xircles.codehaus.org/manage_email

Volker Börchers

unread,
Dec 29, 2012, 11:55:28 PM12/29/12
to us...@groovy.codehaus.org
Bash tries to expand the dollar/variable expression since the dollar is
not escaped:

$ echo "${it@name}"
bash: ${it@name}: bad substitution

In most cases it's the simplest to use outer single quotes and inner
double quotes since the shell doesn't expand strings in single quotes:

$ groovy -e '(new XmlParser().parse("languages.xml")).each{ println
"${it.@name} authored by ${it.author[0].text()}" }'

but it gets nasty if you need inner single quotes:

groovy -e '(new XmlParser().parse('\''languages.xml'\'')).each{
println "${it.@name} authored by ${it.author[0].text()}" }'

Otherwise quote the double quotes and the dollars:

groovy -e "(new XmlParser().parse('languages.xml')).each{ println
\"\${it.@name} authored by \${it.author[0].text()}\"}"

Regards,
Volker

sieg...@heintze.com

unread,
Jan 2, 2013, 10:02:21 PM1/2/13
to us...@groovy.codehaus.org
I've tried all three of the proposed solutions and I still get bad substitution errors from Cygwin bash on Windows 8.

uname -a 
CYGWIN_NT-6.2-WOW64 km 1.7.17(0.262/5/3) 2012-10-19 14:39 i686 Cygwin 

$ groovy -e '(new XmlParser().parse("languages.xml")).each{ println "${it.@name
} authored by ${it.author[0].text()}" }'
/cygdrive/c/Program Files (x86)/Groovy/Groovy-2.0.5/bin/startGroovy: line 228: $

{it.author[0].text()}" }": bad substitution

$ groovy -e '(new XmlParser().parse('\''languages.xml'\'')).each{ println "${it
.@name} authored by ${it.author[0].text()}" }'
/cygdrive/c/Program Files (x86)/Groovy/Groovy-2.0.5/bin/startGroovy: line 228: $

{it.author[0].text()}" }": bad substitution

$ groovy -e "(new XmlParser().parse('languages.xml')).each{ println \"\${it.@na
me} authored by \${it.author[0].text()}\"}"
/cygdrive/c/Program Files (x86)/Groovy/Groovy-2.0.5/bin/startGroovy: line 228: $

{it.author[0].text()}"}": bad substitution

Alan Thompson

unread,
Jan 2, 2013, 11:11:43 PM1/2/13
to us...@groovy.codehaus.org
For many tasks I just bypass the problem by creating small "throwaway" scripts named tmp.groovy with 1-3 lines.  No more quoting problems!  An added benefit:  you don't need to keep re-typing them at the command line - just keep your editor window open!
Alan Thompson

Maarten Boekhold

unread,
Jan 3, 2013, 1:52:10 AM1/3/13
to us...@groovy.codehaus.org
Hi,

Note that your error is coming from the startGroovy script, not from the groovy script that you call directly. What's happening is that your command line is correctly escaped and passed to the "groovy" script. But that in turn then calls the "startGroovy" script, passing your script to startGroovy using "$@", which for you seems to go through another round of shell substitutions.

It's off, because your first example (surround with single quotes) is working on my Ubuntu system, which uses "dash" as /bin/sh. I suspect that this is something specific to the "sh" command used by cygwin.

Maarten

"Volker Börchers"

unread,
Jan 3, 2013, 9:13:00 AM1/3/13
to us...@groovy.codehaus.org
Yes, it's a problem under cygwin. The error occurs in line 228 of https://github.com/groovy/groovy-core/blob/master/src/bin/startGroovy in the "if $cygwin" part:

  eval `echo args$i`="\"$arg\""

This breaks you code since it contains double quotes. This statement seems to be used to convert paths that may appear on the command line to Windows format.

Changing the line to

  eval `echo args$i`="'$arg'"

might help in your case but a better fix would be to use bash arrays instead of eval. Although Cygwin comes with bash by default this needs further checks.

Please try the attached patched startGroovy if it works.

Regards,
Volker
Gesendet: Donnerstag, 03. Januar 2013 um 07:52 Uhr
Von: "Maarten Boekhold" <boek...@yahoo.com>
An: us...@groovy.codehaus.org
Betreff: Re: [groovy-user] How to properly escape groovy one liners for bash
startGroovy
Reply all
Reply to author
Forward
0 new messages