2012-02-20 34 views
14

Tôi đang sử dụng bản vá ruby ​​1.8.7 249. Cách sau đây là cách tốt nhất để truyền các biến môi trường vào lệnh shell mà tôi cần thực hiện từ chương trình ruby ​​của mình?Cách đúng để chuyển các biến môi trường sang lệnh exec shell

fork do  
    ENV['A'] = 'A' 
    exec "/bin/bash -c 'echo $A'" 
end 

Process.wait 
+0

Same cho 'system': http://stackoverflow.com/questions/8301294/shell-out-from-ruby-while-setting-an-môi trường biến –

Trả lời

0

tôi sẽ làm điều đó trong một dòng

exec "/bin/bash -c 'A=hello; echo $A'" 
+1

Tôi thích cách của tôi tốt hơn bởi vì sau đó bạn không phải lo lắng về việc thoát dấu chấm phẩy, dấu nháy đơn, và bất cứ điều gì khác mà bash sẽ giải thích trong một đặc biệt đường. –

11

Các docs for Ruby's exec method dường như chưa đầy đủ, nhưng nó nói rằng có một cuộc tranh cãi đầu tiên bắt buộc gọi env, vì vậy có lẽ chỉ định môi trường. Với một giáo dục đoán và một số thử nghiệm, tôi phát hiện ra rằng đúng cách để sử dụng nó là thế này:

exec({"A"=>"A"}, "/bin/bash -c 'echo $A'") 

EDIT 1: Xin lỗi, không làm việc cho phiên bản cũ của Ruby.

+2

Tôi cũng muốn đề cập đến rằng bạn không cần phải nhận được 'bash' tham gia nếu bạn chỉ đang cố gắng để chạy một chương trình và không cần bất kỳ tính năng vỏ ưa thích. Ví dụ, 'exec ({}," ls ")' hoạt động tốt và nên nhanh hơn một chút vì chúng ta không khởi động bash. –

+0

Câu trả lời tuyệt vời, tôi đã tìm ra điều này trước một năm hoặc hơn trước đây, nhưng vẫn chưa nhận ra đây là cách thích hợp để làm điều đó từ các tài liệu ([rdoc.info] (http://rdoc.info/stdlib /core/1.9.3/Kernel:exec) tài liệu có một chút khác biệt và làm cho nó trông giống như bạn có nghĩa vụ phải đặt băm env sau khi chương trình và args của nó). –

+0

@DavidGrayson: Bạn có chắc chắn rằng nó hoạt động trong 1.8.7? –

3

Đối với 1,8 ~ người dùng - sao chép 1.9 hành vi của exec. Tương tự như nỗ lực ban đầu của OP mặc dù.

def exec_env(hash, cmd) 
    hash.each do |key,val| 
    ENV[key] = val 
    end 
    exec cmd 
end 

exec_env({"A"=>"A"}, "/bin/bash -c 'echo $A'") 
+0

Điều này làm việc cho 'exec' vì' exec' không bao giờ trả về, nhưng lưu ý rằng nó khác với 'system', có cùng chữ ký - các biến môi trường được thiết lập thông qua' system (env_hash, command) 'được đặt cho lệnh, nhưng không còn lại trong 'ENV' của Ruby khi lệnh hoàn thành. –

23

Có một cách rất dễ dàng:

system({"MYVAR" => "42"}, "echo $MYVAR") 

Tất cả tín dụng cho điều này đi vào Avdi: https://stackoverflow.com/a/8301399/171933

+1

Điều đáng chú ý là 'popen3' có cùng hành vi với sự kiểm soát stdin, stdout, stderr xem [https://ruby-doc.org/stdlib-2.4.0/libdoc/open3/rdoc/Open3.html#method -c-popen3] (https://ruby-doc.org/stdlib-2.4.0/libdoc/open3/rdoc/Open3.html#method-c-popen3) –

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