Czy istnieje sposób uruchamiania poleceń wiersza poleceń za pośrednictwem Rubiego? Próbuję stworzyć mały program w Rubim, który dzwoniłby i odbierał / wysyłał przez programy wiersza poleceń, takie jak „screen”, „rcsz” itp.
Byłoby wspaniale, gdybym mógł to wszystko powiązać z Rubim (zapleczem MySQL itp.)
Odpowiedzi:
Tak. Jest kilka sposobów:
za. Użyj
%x
lub '' ':%x(echo hi) #=> "hi\n" %x(echo hi >&2) #=> "" (prints 'hi' to stderr) `echo hi` #=> "hi\n" `echo hi >&2` #=> "" (prints 'hi' to stderr)
Te metody zwrócą standardowe wyjście i przekierują stderr do programu.
b. Zastosowanie
system
:system 'echo hi' #=> true (prints 'hi') system 'echo hi >&2' #=> true (prints 'hi' to stderr) system 'exit 1' #=> nil
Ta metoda zwraca,
true
jeśli polecenie zakończyło się pomyślnie. Przekierowuje wszystkie dane wyjściowe do programu.do. Zastosowanie
exec
:fork { exec 'sleep 60' } # you see a new process in top, "sleep", but no extra ruby process. exec 'echo hi' # prints 'hi' # the code will never get here.
To zastępuje bieżący proces tym utworzonym przez polecenie.
re. (rubin 1.9) użyj
spawn
:spawn 'sleep 1; echo one' #=> 430 spawn 'echo two' #=> 431 sleep 2 # This program will print "two\none".
Ta metoda nie czeka na zakończenie procesu i zwraca PID.
mi. Zastosowanie
IO.popen
:io = IO.popen 'cat', 'r+' $stdout = io puts 'hi' $stdout = IO.new 0 p io.read(1) io.close # prints '"h"'.
Ta metoda zwróci
IO
obiekt, który reprezentuje wejście / wyjście nowego procesu. Jest to również obecnie jedyny znany mi sposób przekazywania danych wejściowych do programu.fa. Użyj
Open3
(w wersji 1.9.2 i nowszych)require 'open3' stdout,stderr,status = Open3.capture3(some_command) STDERR.puts stderr if status.successful? puts stdout else STDERR.puts "OH NO!" end
Open3
ma kilka innych funkcji do uzyskiwania jawnego dostępu do dwóch strumieni wyjściowych. Jest podobny do popen, ale daje dostęp do stderr.źródło
io = IO.popen 'cat > out.log', 'r+'
; zapisuje dane wyjściowe polecenia do „out.log”FileUtils
[ ruby-doc.org/stdlib-1.9.3/libdoc/fileutils/rdoc/FileUtils.html] ?Istnieje kilka sposobów uruchamiania poleceń systemowych w Rubim.
irb(main):003:0> `date /t` # surround with backticks => "Thu 07/01/2010 \n" irb(main):004:0> system("date /t") # system command (returns true/false) Thu 07/01/2010 => true irb(main):005:0> %x{date /t} # %x{} wrapper => "Thu 07/01/2010 \n"
Ale jeśli chcesz faktycznie wykonywać dane wejściowe i wyjściowe za pomocą stdin / stdout polecenia, prawdopodobnie będziesz chciał przyjrzeć się
IO::popen
metodzie, która specjalnie oferuje tę funkcję .źródło
folder = "/" list_all_files = "ls -al #{folder}" output = `#{list_all_files}` puts output
źródło
Tak, jest to z pewnością wykonalne, ale metoda implementacji różni się w zależności od tego, czy dany program „wiersza poleceń” działa w trybie „pełnego ekranu”, czy w trybie wiersza poleceń. Programy napisane dla wiersza poleceń mają tendencję do odczytywania STDIN i zapisywania do STDOUT. Można je wywołać bezpośrednio w Rubim, używając standardowych metod odwrotnych znaków i / lub wywołań system / exec.
Jeśli program działa w trybie „pełnego ekranu”, jak screen lub vi, podejście musi być inne. W przypadku programów takich jak ten powinieneś poszukać implementacji biblioteki „oczekuj” w Ruby. Umożliwi to napisanie scenariusza tego, co spodziewasz się zobaczyć na ekranie i co wysłać, gdy zobaczysz, że te konkretne ciągi pojawiają się na ekranie.
Jest to mało prawdopodobne, aby było to najlepsze podejście i prawdopodobnie powinieneś spojrzeć na to, co próbujesz osiągnąć, i znaleźć odpowiednią bibliotekę / klejnot, aby to zrobić, zamiast próbować zautomatyzować istniejącą aplikację pełnoekranową. Na przykład „ Potrzebujesz pomocy przy komunikacji portu szeregowego w języku Ruby ” dotyczy komunikacji przez port szeregowy, prekursora wybierania numeru, jeśli chcesz to osiągnąć za pomocą wymienionych programów.
źródło
Najczęściej używaną metodą jest
Open3
tutaj używana, moja wersja powyższego kodu edytowana w kodzie z pewnymi poprawkami:require 'open3' puts"Enter the command for execution" some_command=gets stdout,stderr,status = Open3.capture3(some_command) STDERR.puts stderr if status.success? puts stdout else STDERR.puts "ERRRR" end
źródło