Ruby, Diferencia entre exec, system y %x () o Backsticks


¿Cuál es la diferencia entre los siguientes métodos Ruby?

exec, system y %x() o comillas simples inclinadas

Sé que se utilizan para ejecutar comandos de terminal mediante programación a través de Ruby, pero me gustaría saber por qué hay tres formas diferentes de hacer esto.

 330
Author: max, 2011-06-14

3 answers

System

El system el método llama a un programa del sistema. Debe proporcionar el comando como un argumento de cadena a este método. Por ejemplo:

>> system("date")
Wed Sep 4 22:03:44 CEST 2013
=> true

El programa invocado utilizará el actual STDIN, STDOUT y STDERR objetos de su programa Ruby. De hecho, el valor de retorno real es true, false o nil. En el ejemplo la fecha se imprimió a través del objeto IO de STDIN. El método devolverá true si el proceso salió con un estado cero, false si el proceso salió con un estado distinto de cero y nil si la ejecución falló.

Otro efecto secundario es que la variable global $? se establece en un Process::Status objeto. Este objeto contendrá información sobre la llamada en sí, incluyendo el identificador de proceso (PID) del proceso invocado y el estado de salida.

>> system("date")
Wed Sep 4 22:11:02 CEST 2013
=> true
>> $?
=> #<Process::Status: pid 15470 exit 0>

Backsticks

Backticks ( ` ) llama a un programa del sistema y devuelve su salida. A diferencia del primer enfoque, el comando no se proporciona a través de una cadena, sino colocándolo dentro de un par de backsticks.

>> `date`
=> Wed Sep 4 22:22:51 CEST 2013   

La variable global $? también se establece a través de los backsticks. Con comillas simples inclinadas usted también puede hacer uso de interpolación de cadenas.

%x()

Usar %x es una alternativa al estilo backsticks. También devolverá la salida. Al igual que sus parientes %w y %q (entre otros), cualquier delimitador será suficiente siempre y cuando los delimitadores de estilo de corchetes coincidan. Esto significa %x(date), %x{date} y %x-date- son todos sinónimos. Como comillas simples inclinadas %x puede hacer uso de la interpolación de cadenas.

Exec

Utilizando Kernel#exec el proceso actual (su script Ruby) es reemplazado por el proceso invocado a través de exec. El método puede tomar una cadena como argumento. En este caso, la cadena estará sujeta a la expansión del shell. Cuando se utiliza más de un argumento, entonces el primero se utiliza para ejecutar un programa y los siguientes se proporcionan como argumentos para el programa a invocar.

Open3.popen3

A veces la información requerida se escribe en la entrada estándar o error estándar y también necesita obtener control sobre ellos. Aquí Open3.popen3 viene muy bien:

require 'open3'

Open3.popen3("curl http://example.com") do |stdin, stdout, stderr, thread|
   pid = thread.pid
   puts stdout.read.chomp
end
 359
Author: Konrad Reiche,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-20 14:08:39

Aquí hay un diagrama de flujo basado en esta respuesta. Ver también, usando script para emular un terminal.

introduzca la descripción de la imagen aquí

 201
Author: Ian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:47:20

Hacen cosas diferentes. execreemplaza el proceso actual con el nuevo proceso y nunca devuelve. systeminvoca otro proceso y devuelve su valor de salida al proceso actual. Usando backsticks invoca otro proceso y devuelve la salida de ese proceso al proceso actual.

 94
Author: William Pursell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-09 11:14:31