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 }


Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow