Ricerca…


introduzione

Esistono molti modi per interagire con il sistema operativo. Dall'interno di Ruby è possibile eseguire comandi shell o di sistema o processi secondari.

Osservazioni

Exec:
Exec ha funzionalità molto limitate e quando viene eseguito uscirà dal programma Ruby ed eseguirà il comando.

Il comando di sistema:
Il comando di sistema viene eseguito in una sotto-shell invece di sostituire il processo corrente e restituisce true o nill. Il comando di sistema è, come i backtick, un'operazione di blocco in cui l'applicazione principale attende fino al completamento del risultato dell'operazione di sistema. Qui l'operazione principale non deve mai preoccuparsi di catturare un'eccezione sollevata dal processo figlio.

L'output della funzione di sistema sarà sempre vero o nullo a seconda che lo script sia stato eseguito senza errori. Pertanto, ogni errore durante l'esecuzione dello script non verrà passato alla nostra applicazione. L'operazione principale non deve mai preoccuparsi di acquisire un'eccezione generata dal processo figlio. In questo caso l'output è nullo perché il processo figlio ha generato un'eccezione.
Questa è un'operazione di blocco in cui il programma Ruby attenderà fino al completamento dell'operazione del comando prima di procedere.
L'operazione di sistema utilizza fork per eseguire il fork del processo corrente e quindi esegue l'operazione specificata utilizzando exec.

I backtick (`):
Il carattere backtick è solitamente posizionato sotto il tasto escape sulla tastiera. I backtick vengono eseguiti in una sotto-shell invece di sostituire il processo corrente e restituiscono il risultato del comando.
Qui possiamo ottenere l'output del comando ma il programma si bloccherà quando viene generata un'eccezione.
Se esiste un'eccezione nel processo secondario, tale eccezione viene fornita al processo principale e il processo principale potrebbe terminare se l'eccezione non viene gestita. Questa è un'operazione di blocco in cui il programma Ruby attenderà fino al completamento dell'operazione del comando prima di procedere.
L'operazione di sistema utilizza fork per eseguire il fork del processo corrente e quindi esegue l'operazione specificata utilizzando exec.

IO.popen:
IO.popen viene eseguito in un processo secondario. Qui l'input standard del processo secondario e l'uscita standard sono collegati all'oggetto IO.

Popen3:
Popen3 ti consente di accedere allo standard input, allo standard output e all'errore standard.
Gli input e output standard del sottoprocesso verranno restituiti in oggetti IO.

$? (come $ CHILD_STATUS)
Può essere utilizzato con le operazioni backtick, system () o% x {} e fornirà lo stato dell'ultimo comando eseguito dal sistema.
Questo potrebbe essere utile per accedere a exitstatus e alle proprietà pid .

$?.exitstatus

Metodi consigliati per eseguire il codice shell in Ruby:

Open3.popen3 o Open3.capture3:
Open3 in realtà utilizza solo il comando spawn di Ruby, ma offre un'API molto migliore.

Open3.popen3

Popen3 viene eseguito in un sottoprocesso e restituisce stdin, stdout, stderr e wait_thr.

require 'open3'
stdin, stdout, stderr, wait_thr = Open3.popen3("sleep 5s && ls")
puts "#{stdout.read} #{stderr.read} #{wait_thr.value.exitstatus}"

o

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

uscirà: stdout è: stderr è: fatale: non un repository git (o nessuna delle directory madri): .git

o

require 'open3'
cmd = 'ping www.google.com'
Open3.popen3(cmd) do |stdin, stdout, stderr, wait_thr|
  while line = stdout.gets
    puts line
  end
end

produrrà:

Pinging www.google.com [216.58.223.36] con 32 byte di dati:
Risposta da 216.58.223.36: byte = 32 tempo = 16 ms TTL = 54
Risposta da 216.58.223.36: byte = 32 tempo = 10 ms TTL = 54
Risposta da 216.58.223.36: byte = 32 tempo = 21 ms TTL = 54
Risposta da 216.58.223.36: byte = 32 tempo = 29 ms TTL = 54
Statistiche ping per 216.58.223.36:
Pacchetti: Inviato = 4, Ricevuto = 4, Perso = 0 (0% di perdita),
Tempi approssimativi di andata e ritorno in millisecondi:
Minimo = 10 ms, Massimo = 29 ms, Medio = 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

o

Open3.capture3('/some/binary with some args')  

Non consigliato però, a causa di sovraccarico aggiuntivo e il potenziale per iniezioni di shell.

Se il comando legge da stdin e vuoi nutrirlo con alcuni dati:

Open3.capture3('my_funky_command', stdin_data: 'read from stdin')  

Esegui il comando con una diversa directory di lavoro, usando chdir:

Open3.capture3('my_funky_command', chdir: '/some/directory')  

Modi classici per eseguire il codice shell in Ruby:

Exec:

exec 'echo "hello world"'

o

exec ('echo "hello world"')

Il comando di sistema:

system 'echo "hello world"'

Uscirà "ciao mondo" nella finestra di comando.

o

system ('echo "hello world"')

Il comando di sistema può restituire un vero se il comando ha avuto successo o nill quando no.

result = system 'echo "hello world"'
puts result  # will return a true in the command window

I backtick (`):

echo "hello world" Apparirà "Hello World" nella finestra di comando.

Puoi anche prendere il risultato.

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
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow