Ruby Language
Komendy systemu operacyjnego lub powłoki
Szukaj…
Wprowadzenie
Istnieje wiele sposobów interakcji z systemem operacyjnym. Z poziomu Ruby możesz uruchamiać polecenia powłoki / systemowe lub podprocesy.
Uwagi
Exec:
Exec ma bardzo ograniczoną funkcjonalność, a kiedy zostanie wykonany, opuści program Ruby i uruchomi polecenie.
Polecenie systemowe:
Polecenie System działa w podpowłoce zamiast zastępowania bieżącego procesu i zwraca wartość true lub zero. Polecenie systemowe jest, podobnie jak backticks, operacją blokującą, w której główna aplikacja czeka na zakończenie wyniku operacji systemowej. Tutaj główna operacja nigdy nie musi się martwić przechwyceniem wyjątku zgłoszonego w procesie potomnym.
Wynik funkcji systemowej zawsze będzie miał wartość true lub zero, w zależności od tego, czy skrypt został wykonany bez błędu. Dlatego każdy błąd podczas wykonywania skryptu nie zostanie przekazany do naszej aplikacji. Główna operacja nigdy nie musi się martwić przechwyceniem wyjątku zgłoszonego w procesie potomnym. W tym przypadku wynik jest zerowy, ponieważ proces potomny zgłosił wyjątek.
Jest to operacja blokująca, w której program Ruby poczeka na zakończenie działania polecenia przed kontynuowaniem.
Operacja systemowa używa rozwidlenia, aby rozwidlić bieżący proces, a następnie wykonać daną operację za pomocą exec.
Backticks (`):
Znak cofnięcia znajduje się zwykle pod klawiszem Escape na klawiaturze. Backticks działa w podpowłoce zamiast zastępować bieżący proces i zwraca wynik polecenia.
Tutaj możemy uzyskać wynik polecenia, ale program ulegnie awarii po wygenerowaniu wyjątku.
Jeśli w podprocesie występuje wyjątek, ten wyjątek jest przekazywany do procesu głównego, a proces główny może zakończyć się, jeśli wyjątek nie zostanie obsłużony. Jest to operacja blokująca, w której program Ruby poczeka na zakończenie działania polecenia przed kontynuowaniem.
Operacja systemowa używa rozwidlenia, aby rozwidlić bieżący proces, a następnie wykonać daną operację za pomocą exec.
IO.popen:
IO.popen działa w podprocesie. Tutaj standardowe podprocesowe wejście i standardowe wyjście są podłączone do obiektu IO.
Popen3:
Popen3 umożliwia dostęp do standardowego wejścia, standardowego wyjścia i standardowego błędu.
Standardowe dane wejściowe i wyjściowe podprocesu zostaną zwrócone do obiektów IO.
$? (to samo co $ CHILD_STATUS)
Może być używany z operacjami wstecznymi, operacjami system () lub% x {} i podaje status ostatnio wykonanej komendy systemowej.
Może to być przydatne w celu uzyskania dostępu do exitstatus
i pid
.
$?.exitstatus
Zalecane sposoby wykonywania kodu powłoki w Ruby:
Open3.popen3 lub Open3.capture3:
Open3 faktycznie używa po prostu komendy spawn Ruby, ale daje ci znacznie lepsze API.
Open3.popen3
Popen3 działa w podprocesie i zwraca stdin, stdout, stderr i wait_thr.
require 'open3'
stdin, stdout, stderr, wait_thr = Open3.popen3("sleep 5s && ls")
puts "#{stdout.read} #{stderr.read} #{wait_thr.value.exitstatus}"
lub
require 'open3'
cmd = 'git push heroku master'
Open3.popen3(cmd) do |stdin, stdout, stderr, wait_thr|
puts "stdout is:" + stdout.read
puts "stderr is:" + stderr.read
end
wyświetli: stdout is: stderr is: fatal: Nie repozytorium git (ani żadnego z katalogów nadrzędnych): .git
lub
require 'open3'
cmd = 'ping www.google.com'
Open3.popen3(cmd) do |stdin, stdout, stderr, wait_thr|
while line = stdout.gets
puts line
end
end
wyświetli:
Pinging www.google.com [216.58.223.36] z 32 bajtami danych:
Odpowiedź z 216.58.223.36: bajtów = 32 czas = 16 ms TTL = 54
Odpowiedź od 216.58.223.36: bajtów = 32 czas = 10 ms TTL = 54
Odpowiedź od 216.58.223.36: bajtów = 32 czas = 21 ms TTL = 54
Odpowiedź z 216.58.223.36: bajtów = 32 czas = 29 ms TTL = 54
Statystyki ping dla 216.58.223.36:
Pakiety: Wysłane = 4, Otrzymane = 4, Zgubione = 0 (0% straty),
Przybliżone czasy podróży w obie strony w milisekundach:
Minimum = 10 ms, maksimum = 29 ms, średnia = 19 ms
Open3.capture3:
require 'open3'
stdout, stderr, status = Open3.capture3('my_funky_command', 'and', 'some', 'argumants')
if status.success?
# command completed successfully, do some more stuff
else
raise "An error occured"
end
lub
Open3.capture3('/some/binary with some args')
Nie jest to jednak zalecane ze względu na dodatkowe koszty ogólne i możliwość wstrzyknięć do skorupy.
Jeśli polecenie odczytuje ze standardowego wejścia i chcesz podać trochę danych:
Open3.capture3('my_funky_command', stdin_data: 'read from stdin')
Uruchom polecenie z innym katalogiem roboczym, używając chdir:
Open3.capture3('my_funky_command', chdir: '/some/directory')
Klasyczne sposoby wykonywania kodu powłoki w Ruby:
Exec:
exec 'echo "hello world"'
lub
exec ('echo "hello world"')
Polecenie systemowe:
system 'echo "hello world"'
W oknie poleceń wyświetli „hello world”.
lub
system ('echo "hello world"')
Polecenie systemowe może zwrócić wartość true, jeśli polecenie się powiodło, lub zero, gdy nie.
result = system 'echo "hello world"'
puts result # will return a true in the command window
Backticks (`):
echo "hello world"
„hello world” w oknie poleceń.
Możesz także złapać wynik.
result = `echo "hello world"`
puts "We always code a " + result
IO.popen:
# Will get and return the current date from the system
IO.popen("date") { |f| puts f.gets }