While using Grails 2.4.5 org.codehaus.groovy.runtime.ProcessGroovyMethods on Ubuntu 14.04:
def command = "mysqldump -h${databaseProperties.host} -u'${databaseProperties.username}' -p'${databaseProperties.password}' ${databaseProperties.name} " + table
print command
def proc = command.execute()
def oneMinute = 60000
proc.waitForOrKill(oneMinute)
if(proc.exitValue()!=0){
println "[[return code: ${proc.exitValue()}]]"
println "[[stderr: ${proc.err.text}]]"
return null
}else{
return proc.in.text.readLines()
}
I've got
[[return code: 2]]
[[stderr: mysqldump: Got error: 1045: Access denied for user 'root'@'localhost' (using password: YES) when trying to connect]]
but when I copy-paste printlined command into my bash I receive proper dump. What is going on?
I've also tried:
changing mysqldump to full path: /usr/bin/mysqldump
sending arguments as a String array but with the same result.
sending command as a regular String to execute:
"mysqldump -hlocalhost -u'root' -p'password' database table"
it works in system bash, it doesn't as a ProcessGroovyMethod...
Update:
After thinking about this overnight, I'm (still) convinced that the problem is related to your password. Since it's really not a best practice to provide the password on the command line (mysqldump even warns you about this), I think you should change tactics by creating a login-path.
Use the following command to create a login path (this is a one-time step):
Then change the command you're attempting to execute from Groovy to this:
This will work around the issue you're seeing and is more secure.
Original answer:
I was able to replicate the problem.
String.execute()
doesn't use a command shell, and therefore the single quotes are getting passed to mysqldump as if they were part of your password.Edit: After some further thought, I don't think Groovy's
String.execute()
is the way to go here, because of its unexpected handling of quotes. It's fine if your password doesn't include spaces, but this is likely to be brittle.If you need more control, you should consider using
ProcessBuilder
:Edit: Further research, just tested this with a password that includes spaces.
command.execute()
doesn't handle this properly, but using theProcessBuilder
method works.Here's another post explaining some of the unexpected behavior of the String.execute() method:
Groovy: strings with embedded quotes don't execute as expected