Jeśli chcesz uruchomić zewnętrzną komendę z Rubiego…
…jak wkhtmltopdf do konwersji pliku HTML na PDF.
Jest kilka metod Rubiego, których możesz użyć.
Zależnie od metody, której użyjesz otrzymasz różne rezultaty.
Poznajmy te metody razem!
Metoda systemowa Rubiego
Metoda systemowa Rubiego jest najprostszym sposobem na uruchomienie zewnętrznej komendy.
Wygląda to tak:
system("ls")
Zauważ, że system
wydrukuje dane wyjściowe komendy w trakcie jej wykonywania.
System sprawi również, że Twój program Ruby będzie czekał aż polecenie zostanie wykonane.
Spróbuj tego:
system("sleep 2")
Istnieją sposoby na uruchamianie poleceń w tle, jak zobaczymy później.
System może zwrócić 3 możliwe wartości:
-
true
jeśli polecenie zadziałało -
false
jeśli polecenie zwróci kod błędu -
nil
jeśli wykonanie polecenia nie powiedzie się (polecenie nie zostało znalezione)
Możesz uzyskać kod stanu wyjścia ostatniego zewnętrznego polecenia, które wykonałeś za pomocą zmiennej globalnej $?
. Ten kod statusu może dać ci więcej informacji o tym, dlaczego polecenie nie powiodło się.
Co to jest rozszerzenie powłoki?
Kiedy uruchomisz zewnętrzne polecenie z system
, otrzymasz efekt „rozszerzenia powłoki”.
Rozszerzenie powłoki jest wtedy, gdy powłoka (sh/bash/zsh) przyjmuje pewne specjalne znaki (*
, ?
, i ")# "best"
This will not change the current environment of your Ruby application.
%x / Kernel#`
If you want to get the output from the command you're running, instead of displaying it then you can use %x
lub metodę Kernel#`
.
Robią to samo.
Oto przykład:
`ls`
Inny z %x
:
%x|ls|
Te dwa przykłady zwrócą łańcuch z wyjściem polecenia ls
.
Zauważ, że nadal musisz czekać na zakończenie polecenia, chyba że uruchomisz je wewnątrz wątku.
Jak użyć Fork + Exec Aby uruchomić zewnętrzne komendy na oddzielnym procesie
Forking tworzy kopię bieżącego procesu (twojej aplikacji Ruby), następnie możesz zastąpić tę kopię innym procesem używając exec.
Uwaga: Metoda fork nie jest dostępna w Windows.
Jest to popularny wzorzec w świecie Unixa.
Oto jak to działa:
fork { exec("ls") }
To uruchomi ls
na innym procesie & wyświetli jego dane wyjściowe.
Ponieważ to polecenie jest uruchomione w innym procesie, nie zablokuje Twojej aplikacji Ruby przed uruchomieniem jak metoda system
lub %x
.
Ważne:
Jeśli użyjesz exec
bez fork
to zastąpi twój aktualny proces.
To oznacza, że twój program Ruby zostanie zakończony.
How to Use the Popen Method For Two Way Communication With An External Program
Jeśli potrzebujesz:
- Większej kontroli nad procesem
- Dwukierunkowej komunikacji
to metoda IO.popen
jest tym czego szukasz.
W poniższym przykładzie używam metody popen do uruchomienia irb
procesu, następnie wysyłam do niego jakieś dane wejściowe &czytam dane wyjściowe.
Tutaj przykład:
r = IO.popen("irb", "r+")r.write "puts 123 + 1\n"3.times { puts r.gets }r.write "exit\n"
Ta r
zmienna jest obiektem IO, oznacza to, że możesz pisać &czytać z niej jak ze zwykłego pliku.
Używanie popen
oznacza również, że twoje zewnętrzne polecenie będzie działać na własnym procesie, więc nie musisz go uruchamiać na wątku.
Istnieje również metoda popen3
w bibliotece standardowej.
Różnica z regularnym popen
polega na tym, że podzieli ona regularne wyjściowe & komunikaty o błędach na oddzielne obiekty IO.
Zakończenie
Poznałeś różne sposoby interakcji z zewnętrznymi poleceniami w Rubim.
Bądź ostrożny z tymi poleceniami!
Nie przekazuj żadnego rodzaju danych wejściowych użytkownika do tych poleceń, chyba że chcesz mieć problem z bezpieczeństwem w swojej aplikacji w Rubim.