2013-08-12 29 views
5

Bây giờ, tôi đang viết một kịch bản Groovy để gọi giao diện của người khác. Nhưng tôi cần thay đổi đường dẫn làm việc hiện tại của mình khi chạy tập lệnh. Tôi biết điều đó là không thể trong Java. Có thể trong Groovy không?Cách thay đổi thư mục làm việc hiện tại trong Groovy

Trả lời

6

Khi Groovy chạy trên JVM, các hạn chế giống nhau sẽ được áp dụng. Thật không may là không thể.

Changing the current working directory in Java?

JDK bug

+0

hôm qua tôi tìm kiếm nó trên Stackoverflow, nó có thể làm việc theo cách này: 'khoảng trống setCurrentDirectory (new_dir_path) { \t System.setProperty ("user.dir", new_dir_path) } ' – Joe

+0

@Joe Không nó sẽ không, đọc câu hỏi Java tôi đã liên kết. –

+0

Vâng. Tôi đã thử nghiệm, nó sẽ không. Cảm ơn bạn. – Joe

4

Nếu bạn có thể chạy kịch bản khác như quá trình riêng biệt, bạn có thể cho ProcessBuilder tham số dir làm việc:

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

hoặc

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

để quá trình đó sẽ chuyển sang thư mục mới của bạn và thực hiện nó ở đó.

1

Java/groovy không thực sự "Có" một thư mục làm việc theo như tôi có thể nói. Shell khởi chạy groovy có một và bất kỳ "lệnh" con nào được thừa hưởng từ trình bao đó.

Java cũng có vẻ đọc thư mục hiện tại của trình bao và lưu trữ nó trong "user.dir". Điều này được sử dụng như là một cơ sở cho đối tượng "File" vì vậy nếu bạn System.setProperty ("user.dir", "c:/windows") nó sẽ thay đổi lời gọi tương lai của File mới (".") Nhưng sẽ không thay đổi thư mục shell mẹ (và do đó không phải là thư mục con).

Dưới đây là ba "công việc ở quanh" mà có thể làm việc cho các kịch bản khác nhau:

1) Tôi LOẠI vượt qua điều này cho một nhiệm vụ rất cụ thể ... Tôi muốn thực hiện "cd" như một kịch bản hấp dẫn. Nó chỉ có thể bởi vì tất cả các kịch bản của tôi đã được "gói" trong một tập tin thực thi. Tôi đã làm cho nó để kịch bản của tôi có thể tạo ra một tập tin gọi là "afterburner.cmd" rằng, nếu nó tồn tại, sẽ được thực hiện khi kịch bản thoát. Có một số thủ đoạn tập tin thực thi để thực hiện công việc này.

Tệp cmd khởi động cũng có thể "Đặt" thư mục hiện tại trước khi gọi tập lệnh/ứng dụng groovy của bạn. Bằng cách này, có một cmd khởi động đã hữu ích hơn nhiều so với tôi nghĩ nó sẽ là - Nó làm cho môi trường của bạn không đổi và cho phép bạn dễ dàng triển khai "Scripts" của bạn hơn cho các máy khác. Tôi thậm chí còn biên dịch các kịch bản của tôi thành các lớp. Bởi vì nó hóa ra là nhanh hơn để biên dịch một .groovy thành một lớp .class và bắt đầu lớp .class với "Java" hơn là chỉ chạy kịch bản với "groovy" - và thông thường bạn có thể bỏ qua bước biên dịch làm cho nó nhanh hơn rất nhiều!

2) Đối với một vài lệnh nhỏ, bạn có thể viết một phương pháp như thế này:

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") 

nó sẽ chậm hơn so với "" .execute() nếu "cmd" là không cần thiết.

3) Mã một lớp học nhỏ mà duy trì một "Open" lệnh shell (Tôi đã làm điều này một lần, có một chút phức tạp), nhưng ý tưởng là:

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

Now "trong" là một luồng đầu vào mà bạn có thể quay/đọc từ và "ra" là luồng đầu ra mà bạn có thể viết lệnh, theo dõi "lỗi" để phát hiện lỗi.

Lớp nên viết lệnh cho đầu ra, đọc đầu vào cho đến khi lệnh hoàn tất rồi trả về đầu ra cho người dùng.

Sự cố phát hiện khi đầu ra của bất kỳ lệnh đã cho nào hoàn tất. Nói chung, bạn có thể phát hiện dấu nhắc "C: ..." và giả định rằng điều này có nghĩa là lệnh đã thực hiện xong. Bạn cũng có thể sử dụng hết thời gian chờ. Cả hai đều khá dễ đọc. Bạn có thể đặt lời nhắc của trình bao đó thành một thứ gì đó độc đáo để làm cho nó kém dễ dàng hơn.

Lợi thế là vỏ này có thể vẫn mở cho toàn bộ vòng đời của ứng dụng và có thể tăng đáng kể tốc độ vì bạn không liên tục tạo vỏ "cmd". Nếu bạn tạo một lớp (chúng ta hãy gọi nó là "CommandShell") mà kết thúc tốt đẹp đối tượng Process của bạn sau đó nó phải được thực sự dễ sử dụng:

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

Tôi đã viết một lớp groovy như lần này, đó là rất nhiều thử nghiệm và bạn Ví dụ có thể được chuyển vào thùng rác bằng các lệnh như "thoát" nhưng có thể.

Các vấn đề liên quan