Computer >> Máy Tính >  >> Lập trình >> Ruby

Cách chạy các lệnh hệ thống từ Ruby

Nếu bạn muốn chạy một lệnh bên ngoài từ Ruby…

… Như wkhtmltopdf để chuyển đổi tệp HTML thành PDF.

Có một số phương pháp Ruby bạn có thể sử dụng.

Tùy thuộc vào phương pháp bạn sử dụng mà bạn sẽ nhận được các kết quả khác nhau .

Hãy cùng nhau khám phá những phương pháp này!

Phương pháp hệ thống Ruby

Phương thức hệ thống Ruby là cách đơn giản nhất để chạy một lệnh bên ngoài.

Có vẻ như thế này :

system("ls")

Lưu ý rằng system sẽ in đầu ra lệnh khi nó xảy ra.

Ngoài ra, hệ thống sẽ thực hiện chương trình Ruby của bạn đợi cho đến khi lệnh được thực hiện xong .

Hãy thử điều này:

system("sleep 2")

Có nhiều cách để chạy các lệnh trong nền như chúng ta sẽ thấy ở phần sau.

Hệ thống có thể trả về 3 giá trị có thể có :

  • true nếu lệnh hoạt động
  • false nếu lệnh trả về mã lỗi
  • nil nếu thực thi lệnh không thành công (không tìm thấy lệnh)

Bạn có thể nhận mã trạng thái thoát của lệnh bên ngoài cuối cùng mà bạn đã chạy với $? biến toàn cục. Mã trạng thái này có thể cung cấp cho bạn thêm thông tin về lý do tại sao lệnh không thành công.

Shell Expansion là gì?

Khi bạn chạy một lệnh bên ngoài với system bạn sẽ nhận được hiệu ứng "mở rộng vỏ".

Mở rộng shell là khi shell (sh / bash / zsh) nhận một số ký tự đặc biệt (* , ?[ ) từ lệnh của bạn & mở rộng chúng thành danh sách tệp .

Ví dụ:

system("echo *")

Thao tác này sẽ in mọi tệp &thư mục trong thư mục hiện tại.

* được thay thế bằng danh sách các tệp trước khi lệnh chạy.

Nếu bạn muốn sử dụng các ký tự đặc biệt này vì chúng chuyển các đối số làm đối số thứ 2 của system .

Như thế này:

system("echo", "*")

Bây giờ đầu ra sẽ là * .

Cách sử dụng các biến môi trường

Nếu bạn muốn chuyển một biến môi trường cụ thể cho một lệnh bên ngoài bạn có thể sử dụng hàm băm làm đối số đầu tiên .

Đây là một ví dụ:

system({"rubyguides" => "best"}, "ruby", "-e p ENV['rubyguides']")

# "best"

Điều này sẽ không thay đổi môi trường hiện tại của ứng dụng Ruby của bạn.

% x / Kernel # `

Nếu bạn muốn nhận đầu ra từ lệnh bạn đang chạy, thay vì hiển thị nó thì bạn có thể sử dụng %x hoặc Kernel#` phương pháp.

Họ làm điều tương tự.

Đây là một ví dụ :

`ls`

Một cái khác với %x :

%x|ls|

Hai ví dụ này sẽ trả về một chuỗi có đầu ra của ls lệnh.

Lưu ý rằng bạn vẫn phải đợi lệnh kết thúc trừ khi bạn chạy nó bên trong một chuỗi.

Cách sử dụng Fork + Exec để chạy các lệnh bên ngoài trên một quy trình riêng biệt

Forking tạo một bản sao của quy trình hiện tại của bạn (ứng dụng Ruby của bạn), sau đó bạn có thể thay thế bản sao đó bằng một quy trình khác bằng thực thi .

Lưu ý :Phương pháp fork không khả dụng trên Windows.

Đây là một mẫu phổ biến trong thế giới Unix.

Đây là cách hoạt động :

fork { exec("ls") }

Điều này sẽ chạy ls trên một quy trình khác và hiển thị đầu ra của nó.

lệnh này đang chạy trong một quá trình khác nó sẽ không chặn ứng dụng Ruby của bạn chạy giống như hệ thống system phương thức hoặc %x .

Quan trọng:

Nếu bạn sử dụng exec không có fork bạn sẽ thay thế quy trình hiện tại của mình.

Điều này có nghĩa là chương trình Ruby của bạn sẽ kết thúc.

Cách sử dụng phương pháp Popen để giao tiếp hai chiều với chương trình bên ngoài

Nếu bạn cần:

  • Kiểm soát nhiều hơn đối với quy trình
  • Giao tiếp hai chiều

Sau đó, IO.popen phương pháp là những gì bạn đang tìm kiếm.

Trong ví dụ sau, tôi sử dụng phương thức popen để khởi chạy irb xử lý, sau đó gửi một số đầu vào cho nó và đọc đầu ra.

Đây là ví dụ :

r = IO.popen("irb", "r+")

r.write "puts 123 + 1\n"

3.times { puts r.gets }

r.write "exit\n"

r này biến là một đối tượng IO, điều này có nghĩa là bạn có thể ghi và đọc từ nó như một tệp thông thường .

Sử dụng popen cũng có nghĩa là lệnh bên ngoài của bạn sẽ chạy trên quy trình riêng của nó, vì vậy bạn không cần phải chạy nó trên một chuỗi.

Ngoài ra còn có một popen3 trong thư viện chuẩn.

Sự khác biệt với popen thông thường là nó sẽ chia thông báo lỗi và đầu ra thông thường thành các đối tượng IO riêng biệt.

Kết luận

Bạn đã học về các cách khác nhau mà bạn có thể tương tác với các lệnh bên ngoài trong Ruby.

Hãy cẩn thận với những điều này!

Không chuyển bất kỳ loại đầu vào nào của người dùng vào các lệnh này trừ khi bạn muốn bảo mật vấn đề trong ứng dụng Ruby của bạn.

Nếu bạn biết được điều gì mới, vui lòng chia sẻ bài viết này để nhiều người có thể xem nó.

Cảm ơn vì đã đọc 🙂