如何在Groovy中更改当前工作目录

时间:2013-08-12 03:34:53

标签: groovy cwd

现在,我正在编写一个Groovy脚本来调用其他接口。但是我需要在运行脚本时更改当前的工作路径。我知道在Java中不可能。在Groovy中有可能吗?

4 个答案:

答案 0 :(得分:12)

如果您可以将其他脚本作为单独的进程运行,则可以为ProcessBuilder参数提供工作目录:

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

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

以便进程切换到新文件夹并在那里执行。

答案 1 :(得分:7)

当Groovy在JVM上运行时,同样的限制也适用。不幸的是,这是不可能的。

Changing the current working directory in Java?

JDK bug

答案 2 :(得分:2)

据我所知,Java / groovy并没有真正“拥有”一个工作目录。启动groovy的shell有一个,任何子命令“命令”都直接从该shell继承。

Java似乎也会读取shell的当前目录并将其存储在“user.dir”中。这用作“File”对象的基础,因此如果您使用System.setProperty(“user.dir”,“c:/ windows”),它将更改新文件(“。”)的未来调用,但不会更改父shell目录(因此不是子目录)。

以下是三种可能适用于不同情况的“解决方法”:

1)I KIND OF克服了这个非常具体的任务......我想将“cd”作为一个groovy脚本来实现。这是唯一可能的,因为我的所有脚本都已经被“包装”在批处理文件中。我做了这个,以便我的脚本可以创建一个名为“afterburner.cmd”的文件,如果它存在,将在脚本退出时执行。有一些批处理文件技巧可以使这项工作。

启动cmd文件也可以在调用groovy脚本/ app之前“设置”当前目录。

顺便说一句,拥有一个启动cmd比我想象的更有帮助 - 它使你的环境保持不变,并允许你更容易地将你的“脚本”部署到其他机器上。我甚至将我的脚本编译为.classes,因为将.groovy编译为.class并使用“Java”启动.class比使用“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")  

如果不需要“cmd”,它将比“”.execute()慢。

3)编写一个维护“Open”命令shell的小类(我做了一次,有一点复杂性),但想法是:

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

现在“in”是一个可以旋转/读取的输入流,“out”是一个可以编写命令的输出流,密切关注“错误”以检测错误。

该类应该向输出写一个命令,读取输入直到命令完成,然后将输出返回给用户。

问题是检测任何给定命令的输出何时完成。通常,您可以检测到“C:...”提示,并假设这意味着该命令已完成执行。您也可以使用超时。两者都很容易犯错。您可以将该shell的提示设置为独特的,以使其更不易错误。

优点是这个shell可以在应用程序的整个生命周期内保持打开状态,并且可以显着提高速度,因为您不会重复创建“cmd”shell。如果你创建一个包装你的Process对象的类(让我们称它为“CommandShell”),那么它应该非常容易使用:

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

我曾经写过一个像这样的groovy类,这是很多实验,你的实例可以被像“退出”这样的命令所破坏,但它是可能的。

答案 3 :(得分:1)

您可以将其包装在dir块中。 例如:

dir('yourdirectory') {
   codeblock
}