Cómo llamar comandos de shell desde Ruby
¿Cómo llamo comandos de shell desde dentro de un programa Ruby? ¿Cómo puedo entonces recuperar el resultado de estos comandos en Ruby?
Esta explicación se basa en un script Ruby comentado por un amigo mío. Si desea mejorar el script, no dude en actualizarlo en el enlace.
Primero, tenga en cuenta que cuando Ruby llama a un shell, normalmente llama a /bin/sh
, no a Bash. Algunas sintaxis de Bash no son compatibles con /bin/sh
todos los sistemas.
A continuación se muestran formas de ejecutar un script de shell:
cmd = "echo 'hi'" # Sample string that can be used
Kernel#`
, comúnmente llamados comillas invertidas –`cmd`
Es como muchos otros lenguajes, incluidos Bash, PHP y Perl.
Devuelve el resultado (es decir, la salida estándar) del comando de shell.
Documentos: http://ruby-doc.org/core/Kernel.html#method-i-60
value = `echo 'hi'` value = `#{cmd}`
Sintaxis incorporada,
%x( cmd )
Después del
x
carácter hay un delimitador, que puede ser cualquier carácter. Si el delimitador es uno de los caracteres(
,[
,{
o<
, el literal consta de los caracteres hasta el delimitador de cierre coincidente, teniendo en cuenta los pares de delimitadores anidados. Para todos los demás delimitadores, el literal comprende los caracteres hasta la siguiente aparición del carácter delimitador.#{ ... }
Se permite la interpolación de cadenas .Devuelve el resultado (es decir, la salida estándar) del comando de shell, al igual que las comillas invertidas.
Documentos: https://docs.ruby-lang.org/en/master/syntax/literals_rdoc.html#label-Percent+Strings
value = %x( echo 'hi' ) value = %x[ #{cmd} ]
Kernel#system
Ejecuta el comando dado en un subshell.
Devuelve
true
si el comando se encontró y se ejecutó correctamente;false
en caso contrario.Documentos: http://ruby-doc.org/core/Kernel.html#method-i-system
wasGood = system( "echo 'hi'" ) wasGood = system( cmd )
Kernel#exec
Reemplaza el proceso actual ejecutando el comando externo dado.
No devuelve ninguno, el proceso actual se reemplaza y nunca continúa.
Documentos: http://ruby-doc.org/core/Kernel.html#method-i-exec
exec( "echo 'hi'" ) exec( cmd ) # Note: this will never be reached because of the line above
Aquí hay algunos consejos adicionales:
$?
, que es lo mismo que $CHILD_STATUS
, accede al estado del último comando ejecutado por el sistema si usa las comillas invertidas, system()
o %x{}
. Luego puede acceder a las propiedades exitstatus
y pid
:
$?.exitstatus
Para más lecturas ver:
- http://www.elctech.com/blog/im-in-ur-commandline-executin-ma-commands
- http://blog.jayfields.com/2006/06/ruby-kernel-system-exec-and-x.html
- http://tech.natemurray.com/2007/03/ruby-shell-commands.html
Aquí hay un diagrama de flujo basado en " Cuándo usar cada método para iniciar un subproceso en Ruby ". Consulte también " Engañar a una aplicación para que piense que su salida estándar es una terminal, no una tubería ".