Groovy:嵌入式引号的字符串不会按预期执行 [英] Groovy: strings with embedded quotes don't execute as expected

查看:87
本文介绍了Groovy:嵌入式引号的字符串不会按预期执行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这很奇怪:使用groovy字符串来保存一些命令行来执行,我发现有时如果字符串中存在引号字符,那么执行会简单地失败。

WTF? (更新,见下文)

这是我的测试程序:

  print1:; grep nameserver /etc/resolv.conf\".execute().text.eachLine {println it}; println
print2:; grep'nameserver'/etc/resolv.conf\".execute().text.eachLine {println it}; println
print3:; grep nameserver /etc/resolv.conf\"\"\".execute().text.eachLine {println it}; println
print4:; grepnameserver/etc/resolv.conf\"\"\".execute().text.eachLine {println it}; println
print5:; grep'nameserver'/etc/resolv.conf\"\"\".execute().text.eachLine {println it}; println
print6:; awk / nameserver / /etc/resolv.conf.execute()。text.eachLine {println it}; println
print7:; awk/ nameserver /'/etc/resolv.conf\".execute()。text.eachLine {println it}; println
print8:; awk/ nameserver //etc/resolv.conf。execute()。text.eachLine {println it}; println
print9:; awk'/ nameserver /'/etc/resolv.conf。execute()。text.eachLine {println it}; println
print10:; awk/ nameserver / {print \ $ 2}/etc/resolv.conf。execute()。text.eachLine {println it}; println
返回

结果如下:

  $ groovy weird.groovy 
1:nameserver 10.3.0.101
nameserver 10.4.1.237
nameserver 10.2.1.34

2:
3:nameserver 10.3.0.101
nameserver 10.4.1.237
nameserver 10.2.1.34

4:
5:
6:nameserver 10.3.0.101
nameserver 10.4.1.237
nameserver 10.2.1.34

7:
8:nameserver 10.3.0.101
nameserver 10.4 .1.237
nameserver 10.2.1.34
域名lnx.copansys.com
搜索lnx.copansys.com tst.copansys.com copansys.com

9:
10:

更新



下面是另外一个例子: $ b bash -c echo Hello.execute ().text.eachLine {println it}
bash -c echo'Hello'。execute()。text.eachLine {println it}
bash -c echo \'Hello\ '.execute()。text.eachLine {println it}

结果:

  groovy> bash -c echo Hello.execute()。text.eachLine {println it} 
groovy> bash -c echo'Hello'。execute()。text.eachLine {println it}
groovy> bash -c echo \'Hello\'。execute()。text.eachLine {println it}

'Hello!'

观察嵌入反斜杠引用的'似乎没有帮助。

解决方案

使用 String.execute()执行命令时,它们不会被命令shell解析。引号被传递给执行的实际命令;在这种情况下,grep和awk。



通过用echo替换grep和awk来说明:

  print1:; echo something.execute()。text.eachLine {println it}; println
print2:; echo'something'。execute()。text.eachLine {println it}; println
print3:; echo something。execute()。text.eachLine {println it}; println
print4:; echosomething.execute()。text.eachLine {println it}; println
print5:; echo'something'。execute()。text.eachLine {println it}; println

结果如下:

 1:something 

2:'something'

3:something

4:something

5:'something'

一个简单的解决方法是构建命令行作为字符串列表:

  [awk,'BEGIN {printhello}']。execute() .text 

如果您需要更好地控制命令解析的方式,请查看 ProcessBuilder ,Java类 String.execute()围绕着。


This is weird: using groovy strings to hold some command lines for execution, I find that sometimes if there are quote characters inside the string, the execution simply silently fails.

WTF? (Updated, see below.)

Here's my test program:

print " 1: " ; "grep nameserver /etc/resolv.conf".execute().text.eachLine {println it }          ; println ""
print " 2: " ; "grep 'nameserver' /etc/resolv.conf".execute().text.eachLine {println it }        ; println ""
print " 3: " ; """grep nameserver /etc/resolv.conf""".execute().text.eachLine {println it }      ; println ""
print " 4: " ; """grep "nameserver" /etc/resolv.conf""".execute().text.eachLine {println it }    ; println ""
print " 5: " ; """grep 'nameserver' /etc/resolv.conf""".execute().text.eachLine {println it }    ; println ""
print " 6: " ; "awk /nameserver/ /etc/resolv.conf".execute().text.eachLine{ println it }         ; println ""
print " 7: " ; "awk '/nameserver/' /etc/resolv.conf".execute().text.eachLine{ println it }       ; println ""
print " 8: " ; """awk "/nameserver/" /etc/resolv.conf""".execute().text.eachLine{ println it }   ; println ""
print " 9: " ; """awk '/nameserver/' /etc/resolv.conf""".execute().text.eachLine{ println it }   ; println ""
print "10: " ; """awk "/nameserver/{print \$2}" /etc/resolv.conf""".execute().text.eachLine{ println it }   ; println ""
return

Here's the results:

$ groovy weird.groovy 
 1: nameserver 10.3.0.101
nameserver 10.4.1.237
nameserver 10.2.1.34

 2: 
 3: nameserver 10.3.0.101
nameserver 10.4.1.237
nameserver 10.2.1.34

 4: 
 5: 
 6: nameserver 10.3.0.101
nameserver 10.4.1.237
nameserver 10.2.1.34

 7: 
 8: nameserver 10.3.0.101
nameserver 10.4.1.237
nameserver 10.2.1.34
domain lnx.copansys.com
search lnx.copansys.com tst.copansys.com copansys.com

 9: 
10: 

Update

Here's another example:

"bash -c echo Hello".execute().text.eachLine{ println it }
"bash -c echo 'Hello'".execute().text.eachLine{ println it }
"bash -c echo \'Hello\'".execute().text.eachLine{ println it }

Results:

groovy> "bash -c echo Hello".execute().text.eachLine{ println it } 
groovy> "bash -c echo 'Hello'".execute().text.eachLine{ println it } 
groovy> "bash -c echo \'Hello\'".execute().text.eachLine{ println it } 

'Hello!'

Observe that embedding a backslash-quoted ' doesn't seem to help.

解决方案

When you execute commands with String.execute(), they don't get parsed by a command shell. The quotes are passed through to the actual commands executed; in this case, grep and awk.

This is illustrated by replacing grep and awk with echo:

print " 1: " ; "echo something".execute().text.eachLine {println it }          ; println ""
print " 2: " ; "echo 'something'".execute().text.eachLine {println it }        ; println ""
print " 3: " ; """echo something""".execute().text.eachLine {println it }      ; println ""
print " 4: " ; """echo "something" """.execute().text.eachLine {println it }   ; println ""
print " 5: " ; """echo 'something'""".execute().text.eachLine {println it }    ; println ""

Which results in:

 1: something

 2: 'something'

 3: something

 4: "something"

 5: 'something'

A simple workaround is to build the command line as a list of strings:

["awk", 'BEGIN { print "hello" }'].execute().text

If you need finer control over the how the command is parsed, take a look at ProcessBuilder, the Java class String.execute() is built around.

这篇关于Groovy:嵌入式引号的字符串不会按预期执行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆