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.
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
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.
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. exec
reemplaza el proceso actual con el nuevo proceso y nunca devuelve. system
invoca 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.
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