Как изменить текущий рабочий каталог в Groovy

теперь я пишу Groovy скрипт для вызова интерфейса другого. Но мне нужно изменить мой текущий рабочий путь при запуске сценария. Я знаю, что это невозможно на Java. Возможно ли это в Groovy?

3 ответов


поскольку Groovy работает на JVM, применяются те же ограничения. К сожалению, это невозможно.

изменение текущего рабочего каталога в Java?

ошибка JDK


Если вы можете запустить другой скрипт как отдельный процесс, вы можете дать параметр ProcessBuilder рабочий dir:

def processBuilder=new ProcessBuilder(command)
processBuilder.directory(new File("Working dir"))
def process = processBuilder.start()

или

command.execute(null, new File("Working dir"))

Так что процесс перейдет в новую папку и запустить его там.


Java / groovy на самом деле не "имеет" рабочего каталога, насколько я могу судить. Оболочка, которая запустила groovy, имеет одну и любые дочерние "команды"наследуются от этой оболочки.

Java также, похоже, читает текущий каталог оболочки и сохраняет его в "user.dir." Это используется в качестве базы для объекта "файл", поэтому, если вы система.setProperty ("пользователь.реж.", "c:/windows") это изменит будущие вызовы нового файла ("."), но не изменит родительский каталог оболочки (и поэтому не дочерние каталоги).

вот три "обходных пути", которые могут работать для разных сценариев:

1) я вроде как преодолел это для очень конкретной задачи... Я хотел реализовать " cd " как заводной скрипт. Это было возможно только потому, что все мои скрипты уже были "завернуты" в пакетный файл. Я сделал так, чтобы мой скрипт мог создать файл под названием "afterburner.cmd", который, если бы он существовал, был бы выполнен при выходе скрипта. Был какой-то пакетный файл хитрость, чтобы это сработало.

файл cmd запуска также может "установить" текущий каталог перед вызовом вашего скрипта/приложения groovy.

кстати, наличие запуска cmd было намного полезнее, чем я думал, что это будет-это делает вашу среду постоянной и позволяет вам легче развертывать ваши "скрипты" на других машинах. У меня даже есть свои сценарии.классы, потому что оказалось быстрее скомпилировать a .заводной до А.класс и начинайте .класс с "Java", чем просто запустить скрипт с"groovy" - и обычно вы можете пропустить шаг компиляции, что делает его намного быстрее!

2) для нескольких небольших команд вы можете написать такой метод:

def currentDir = "C:\"
def exec(command, dir = null) {
    "cmd /c cd /d ${dir?:currentDir} && $command".execute().text
}

// Default dir is currentDir
assert exec("dir").endsWith("C:\>")

// different dir for this command only
assert exec("dir", "c:\users").endsWith("C:\users") 

// Change default dir
currentDir = "C:\windows"
assert exec("dir").endsWith("C:\windows")  

это будет медленнее, чем "".execute (), если "cmd" не требуется.

3) Код небольшой класс, который поддерживает" открытую " командную оболочку (я сделал это один раз, есть немного сложности), но идея:

def process="cmd".execute()
def in=process.in
def out=process.out
def err=process.err

Теперь "in" - это входной поток то, что вы можете отключить/прочитать и "из", - это выходной поток, в который вы можете писать команды, следить за "err" для обнаружения ошибок.

класс должен написать команду на выход, прочитать вход, пока команда не будет завершена, а затем вернуть вывод пользователю.

проблема заключается в обнаружении, когда вывод любой данной команды завершен. В общем, вы можете обнаружить " C:..."подскажите и предположите, что это означает, что команда завершила выполнение. Ты мог бы ... также используйте тайм-аут. Оба довольно ненадежны. Вы можете установить приглашение этой оболочки на что-то уникальное, чтобы сделать его гораздо менее ошибочным.

преимущество в том, что эта оболочка может оставаться открытой в течение всей жизни вашего приложения и может значительно увеличить скорость, так как вы не создаете повторно оболочки "cmd". Если вы создаете класс (назовем его "CommandShell"), который обертывает ваш объект процесса, он должен быть очень простым в использовании:

def cmd=new CommandShell()
println cmd.execute("cd /d c:\")
println cmd.execute("dir") // Will be the dir of c:\

Я написал классный класс, как на этот раз это много экспериментов, и ваш экземпляр может быть уничтожен командами типа "выход", но это возможно.