Groovy代码是:
def cmd = "sed -i \'1 i <?xml version=\"1.1\"?>\' test.xml"
println cmd
println cmd.execute().err.text
输出:
sed -i '1 i <?xml version="1.1"?>' test.xml
sed: -e expression #1, char 1: unknown command: `''
这是在cli中运行良好的实际命令sed -i '1 i <?xml version="1.1"?>' test.xml
。但Groovy execute()
无法正常工作。如何解决这个问题?
更新1:
还尝试使用以下cmd
,但仍显示相同的错误。
def cmd = /sed -i '1 i <?xml version="1.1"?>' test.xml/
def cmd = "sed -i '1 i <?xml version=\"1.1\"?>' test.xml"
更新注意:
检查和更新xml文件,
def insertversion(String filename)
{
def lines= new File (filename).readLines()
if(!(lines.get(0)).contains('xml version'))
{
def cmd = ['sed', '-i', '1 i <?xml version="1.1"?>', filename]
cmd.execute()
}
}
答案 0 :(得分:3)
在这种情况下,执行shell命令作为cmd和参数的列表,而不是执行命令为String:
def cmd = ['sed', '-i', '1 i <?xml version="1.1"?>', 'test.xml']
println cmd
println cmd.execute().err.text
在运行脚本后,此部分<?xml version="1.1">
在test.xml
文件中重复(与从命令行运行给定命令的行为相同)。
List.execute()
和String.execute()
之间的区别是什么?如果以字符串形式执行shell命令,java.lang.Runtime.exec()
方法将使用java.util.StringTokenizer
将输入字符串拆分为数组。在您的情况下,tokenizer将创建7个令牌,您可以通过运行以下脚本来检查它:
def cmd = "sed -i \'1 i <?xml version=\"1.1\"?>\' test.xml"
def tokenizer = new StringTokenizer(cmd)
def tokens = []
while (tokenizer.hasMoreTokens()) {
tokens << tokenizer.nextToken()
}
tokens.each { println it }
输出:
sed
-i
'1
i
<?xml
version="1.1"?>'
test.xml
您还可以通过运行调试器来验证它,并在第96行的java.lang.Runtime
类中设置检查点:
这当然是不正确的。使用列表执行shell命令时,我们将获得正确的命令行参数数组:
一般的经验法则是,如果你的shell命令包含可能会混淆java.util.StringTokenizer
的字符,最好使用列表来定义正确的命令行参数列表。