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

如何在Groovy中更改当前工作目录,groovy,cwd,Groovy,Cwd,现在,我正在编写一个Groovy脚本来调用其他人的接口。但是我需要在运行脚本时更改当前的工作路径。我知道这在Java中是不可能的。在Groovy中可能吗?当Groovy在JVM上运行时,同样的限制也适用。不幸的是,这是不可能的 如果可以将其他脚本作为单独的进程运行,则可以为ProcessBuilder参数working dir: def processBuilder=new ProcessBuilder(command) processBuilder.directory(new File("W

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

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


如果可以将其他脚本作为单独的进程运行,则可以为ProcessBuilder参数working dir:

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


因此,该进程将切换到新文件夹并在那里执行。

据我所知,Java/groovy实际上“没有”一个工作目录。启动groovy的shell有一个子“命令”直接从该shell继承

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

以下是三种可能适用于不同场景的“变通方法”:

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

启动cmd文件还可以在调用groovy脚本/应用程序之前“设置”当前目录

顺便说一句,使用startup cmd比我想象的要有用得多——它使您的环境保持不变,并允许您更轻松地将“脚本”部署到其他机器上。我甚至把我的脚本编译成.class,因为事实证明,将.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) 编写一个维护“开放”命令shell的小类(我做过一次,有点复杂),但其思想是:

def process="cmd".execute()
def in=process.in
def out=process.out
def err=process.err
现在,“in”是一个可以派生/读取的输入流,“out”是一个可以编写命令的输出流,注意“err”以检测错误

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

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

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

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

我曾经编写过这样一个groovy类,它需要大量的实验,您的实例可能会被“exit”之类的命令破坏,但这是可能的。

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


昨天我在Stackoverflow上搜索它,它可以这样工作吗?:
void setCurrentDirectory(new_dir_path){System.setProperty(“user.dir”,new_dir_path)}
。我已经测试过了,不会。谢谢。我想这只对詹金斯有效
def cmd=new CommandShell()
println cmd.execute("cd /d c:\\")
println cmd.execute("dir") // Will be the dir of c:\
dir('yourdirectory') {
   codeblock
}