Плохой результат от Groovy's ProcessGroovyMethods (UNIXProcess)
При использовании Grails 2.4.5 http://docs.groovy-lang.org/latest/html/api/org/codehaus/groovy/runtime/ProcessGroovyMethods.html в 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()
}
у меня есть
[[return code: 2]]
[[stderr: mysqldump: Got error: 1045: Access denied for user 'root'@'localhost' (using password: YES) when trying to connect]]
но когда я копирую и вставляю команду printlined в мой bash, я получаю правильный дамп. Что здесь происходит?
Я также попробовал:
изменение mysqldump на полный путь: / usr / bin / mysqldump
отправка аргументов в виде массива String, но с тем же результатом.
отправка команды в виде обычной строки для выполнения:
"mysqldump -hlocalhost -u'root' -p'password' database table"
это работает в системе Bash, это не как ProcessGroovyMethod...
1 ответ
Обновление:
Подумав об этом в одночасье, я (до сих пор) убежден, что проблема связана с вашим паролем. Поскольку ввод пароля в командной строке действительно не рекомендуется (mysqldump даже предупреждает вас об этом), я думаю, вам следует изменить тактику, создав путь для входа в систему.
Используйте следующую команду для создания пути входа (это однократный шаг):
mysql_config_editor set --login-path=name --host=localhost --user=youruser --password
Затем измените команду, которую вы пытаетесь выполнить, с Groovy на следующую:
def command="mysqldump --login-path=name database table"
Это поможет обойти проблему, с которой вы столкнулись, и станет более безопасным.
Оригинальный ответ:
Я был в состоянии повторить проблему. String.execute()
не использует командную оболочку, и поэтому одинарные кавычки передаются mysqldump, как если бы они были частью вашего пароля.
Изменить: После некоторых дальнейших размышлений, я не думаю, что Groovy's String.execute()
это путь сюда, из-за его неожиданной обработки кавычек. Хорошо, если ваш пароль не содержит пробелов, но это, вероятно, будет хрупким.
Если вам нужно больше контроля, вы должны рассмотреть возможность использования ProcessBuilder
:
ProcessBuilder pb = new ProcessBuilder("mysqldump", "-h${databaseProperties.host}", "-u${databaseProperties.username}", "-p${databaseProperties.password}", databaseProperties.name, table);
pb.inheritIO();
Process p = pb.start();
Изменить: Дальнейшее исследование, только что проверил это с паролем, который включает пробелы. command.execute()
не обрабатывает это должным образом, но используя ProcessBuilder
метод работает.
Вот еще один пост, объясняющий некоторые неожиданные действия метода String.execute():
Groovy: строки со встроенными кавычками не выполняются должным образом