Buscar..


Introducción

Hay muchas formas de interactuar con el sistema operativo. Desde dentro de Ruby puede ejecutar comandos / sub-procesos de shell / sistema.

Observaciones

Exec:
Exec tiene una funcionalidad muy limitada y, cuando se ejecute, saldrá del programa Ruby y ejecutará el comando.

El Comando del Sistema:
El comando del sistema se ejecuta en un sub-shell en lugar de reemplazar el proceso actual y devuelve true o nill. El comando del sistema es, como backticks, una operación de bloqueo donde la aplicación principal espera hasta que se complete el resultado de la operación del sistema. Aquí, la operación principal nunca debe preocuparse por capturar una excepción generada desde el proceso hijo.

La salida de la función del sistema siempre será verdadera o nula dependiendo de si el script se ha ejecutado o no sin error. Por lo tanto, todos los errores al ejecutar el script no se pasarán a nuestra aplicación. La operación principal nunca debe preocuparse por capturar una excepción provocada por el proceso secundario. En este caso, la salida es nula porque el proceso hijo generó una excepción.
Esta es una operación de bloqueo en la que el programa Ruby esperará hasta que finalice la operación del comando antes de continuar.
La operación del sistema usa la bifurcación para bifurcar el proceso actual y luego ejecuta la operación dada usando exec.

Los backticks (`):
El carácter de comilla invertida generalmente se encuentra debajo de la tecla Escape del teclado. Backticks se ejecuta en un sub-shell en lugar de reemplazar el proceso actual y devuelve el resultado del comando.
Aquí podemos obtener la salida del comando, pero el programa se bloqueará cuando se genere una excepción.
Si hay una excepción en el subproceso, esa excepción se otorga al proceso principal y el proceso principal podría terminar si no se maneja la excepción. Esta es una operación de bloqueo en la que el programa Ruby esperará hasta que finalice la operación del comando antes de continuar.
La operación del sistema usa la bifurcación para bifurcar el proceso actual y luego ejecuta la operación dada usando exec.

IO.popen:
IO.popen se ejecuta en un subproceso. Aquí, la entrada estándar del subproceso y la salida estándar se conectan al objeto IO.

Popen3:
Popen3 le permite acceder a la entrada estándar, la salida estándar y el error estándar.
La entrada y salida estándar del subproceso se devolverán a los objetos de E / S.

PS (igual que $ CHILD_STATUS)
Se puede usar con las operaciones backticks, system () o% x {} y dará el estado del último comando ejecutado del sistema.
Esto podría ser útil para acceder a las exitstatus y pid .

$?.exitstatus

Formas recomendadas para ejecutar código de shell en Ruby:

Open3.popen3 o Open3.capture3:
Open3 en realidad solo usa el comando spawn de Ruby, pero te da una API mucho mejor.

Open3.popen3

Popen3 se ejecuta en un subproceso y devuelve stdin, stdout, stderr y 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

dará salida: stdout es: stderr es: fatal: no es un repositorio git (o cualquiera de los directorios principales): .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

saldrá:

Hacer ping en www.google.com [216.58.223.36] con 32 bytes de datos:
Respuesta de 216.58.223.36: bytes = 32 tiempo = 16 ms TTL = 54
Respuesta de 216.58.223.36: bytes = 32 tiempo = 10 ms TTL = 54
Respuesta de 216.58.223.36: bytes = 32 tiempo = 21 ms TTL = 54
Respuesta de 216.58.223.36: bytes = 32 tiempo = 29ms TTL = 54
Estadísticas de ping para 216.58.223.36:
Paquetes: Enviados = 4, Recibidos = 4, Perdidos = 0 (0% de pérdida),
Tiempo aproximado de ida y vuelta en milisegundos:
Mínimo = 10 ms, Máximo = 29 ms, promedio = 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')  

Sin embargo, no se recomienda, debido a la sobrecarga adicional y al potencial de inyecciones de shell.

Si el comando se lee desde la entrada estándar y desea alimentar algunos datos:

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

Ejecute el comando con un directorio de trabajo diferente, usando chdir:

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

Formas clásicas de ejecutar código shell en Ruby:

Exec:

exec 'echo "hello world"'

o

exec ('echo "hello world"')

El Comando del Sistema:

system 'echo "hello world"'

Saldrá "hola mundo" en la ventana de comandos.

o

system ('echo "hello world"')

El comando del sistema puede devolver un verdadero si el comando fue exitoso o nulo cuando no lo fue.

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

Los backticks (`):

echo "hello world" Saldrá "hello world" en la ventana de comandos.

También puedes coger el resultado.

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
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow