2012-04-13 10 views
44

tôi biết làm thế nào để chạy một lệnh shell trong Ruby như:của Ruby lệnh chạy shell trong một thư mục cụ thể

%x[#{cmd}] 

Nhưng, làm thế nào để tôi chỉ định một thư mục để chạy lệnh này?

Có cách nào tương tự bắn phá ra, tương tự như subprocess.Popen bằng Python:

subprocess.Popen(r'c:\mytool\tool.exe', cwd=r'd:\test\local') 

Cảm ơn!

Trả lời

109

Bạn có thể sử dụng phiên bản chặn của Dir.chdir. Bên trong khối bạn đang ở trong thư mục được yêu cầu, sau khi Khối bạn vẫn nằm trong thư mục theo thời gian:

Dir.chdir('mydir'){ 
    %x[#{cmd}] 
} 
+3

+1 Có vẻ như quá ít người lập trình Ruby biết về điều này. – Phrogz

+5

Những thứ như thế này mà Ruby làm với các khối không bao giờ ngừng làm tôi ngạc nhiên. Ruby liên tục làm cho các ngôn ngữ khác của tôi cảm thấy bối rối và quá phức tạp. – bta

+0

Điều này thật tuyệt vời, tôi mới biết điều này trước đó! – ZirconCode

10

của Ruby 1.9.3 (chặn cuộc gọi):

require 'open3' 
Open3.popen3("pwd", :chdir=>"/") {|i,o,e,t| 
    p o.read.chomp #=> "/" 
} 

Dir.pwd #=> "/home/abe" 
1

Có lẽ nó không phải là giải pháp tốt nhất, nhưng cố gắng sử dụng Dir.pwd để có được thư mục hiện hành và lưu nó ở đâu đó. Sau đó sử dụng Dir.chdir (đích), nơi đích là một thư mục mà bạn muốn chạy lệnh của bạn từ đó. Sau khi chạy lệnh sử dụng Dir.chdir một lần nữa, sử dụng thư mục đã lưu trước đó để khôi phục lại nó.

+2

Bạn cũng có thể sử dụng phiên bản chặn của 'Dir.chdir'. Bên trong khối bạn đang ở trong thư mục được yêu cầu, sau khi Chặn bạn vẫn còn trong thư mục trước đó. – knut

+0

@knut Bạn nên làm cho câu trả lời đó - tôi thích nó! Tôi sẽ đề nghị một cái gì đó điên rồ như 'Dir.chdir (Dir.pwd.tap {Dir.chdir (' d: \ test \ local '); #otherstuff}) 'như tôi không biết chdir có thể lấy một khối –

+0

@AbeVoelker Bạn nói đúng, [ở đây là] (http://stackoverflow.com/a/10148325/676874) – knut

4

cũng có, đi theo con đường vỏ

%x[cd #{dir} && #{cmd}] 
1

Tôi có vấn đề này giống nhau và giải quyết nó bằng cách đặt cả lệnh trong ve lưng và tách với '& &':

`cd \desired\directory && command` 
1

gần nhất tôi thấy để backtricks với dir thay đổi an toàn được capture2:

require 'open3' 
output, status = Open3.capture2('pwd', :chdir=>"/tmp") 

Bạn có thể xem các phương pháp Open3 hữu ích khác trong tài liệu ruby. Một hạn chế là hỗ trợ jruby cho open3 là khá bị hỏng.