2009-12-25 16 views
23

No estoy seguro si esto tiene sentido, pero estoy pensando si hay una manera de suprimir el resultado mostrado para un comando cuando se ejecuta usando el método system en ruby? Quiero decir que debería simplemente dar como resultado verdadero o falso a STDOUT y no a la salida del comando. Lo que creo es que solo se puede hacer si el comando se puede ejecutar en silencio y no desde el método system. ¿Puede alguien proporcionar un poco más de conocimiento?Suprimir la salida de un comando ejecutado usando el método 'system' mientras se ejecuta en un script de ruby ​​

Respuesta

20

Después de llamar a system el código de salida está en la variable $? especial por lo que si useradd devuelve valores diferentes para indicar si el usuario se ha añadido correctamente (por ejemplo, 0 para el éxito) entonces usted puede hacer lo siguiente:

system('useradd xx > /dev/null') 
if $? == 0 
    puts 'added' 
else 
    puts 'failed' 
end 

donde la redirección a /dev/null suprimirá la salida.

Alternativamente, si el programa que se está llamando no utiliza su código de salida para indicar el éxito o el fracaso, puede utilizar los trazos y buscar una subcadena particular en la salida, p.

if `useradd xx`.include? 'success' 
    puts 'it worked' 
else 
    puts 'failed to add user' 
end 
+0

comprobando que el estado de salida parece funcionar perfecto. Gracias. – kilari

+6

Esto solo no suprimirá 'stderr'. Debería usar este 'sistema ('useradd xx>/dev/null 2> & 1')' – Dex

+0

'system' también devuelve' true' o 'false' y me gusta especialmente depender de esos valores simples. Los valores devueltos no se ven afectados por la redirección '>/dev/null 2> & 1'. – Ikon

-1

También puede utilizar acentos abiertos o% x

+0

sí, pero no podré usarlo como condición para ejecutar algunas afirmaciones que puedo hacer cuando uso 'system' – kilari

+2

Eso tiene muy poco sentido, así que tal vez deba publicar un ejemplo real. –

+0

Así que escriba un condicional diferente que en realidad analiza el resultado y podría ser una mejor idea que la que tiene ahora. –

7

Como una adición, me ha sorprendido un par de veces cuando yo he usado acentos abiertos y vio la salida "deslizamiento" del pasado mi variables al ejecutar secuencias de comandos desde la línea de comandos.

Invariablemente, el problema es que el texto que estoy viendo proviene en realidad de stderr en lugar de stdout. Entonces, para cambiar ese texto a stdout también, recuerde agregar 2>&1 al comando que está tratando de ejecutar.

Espero que sea útil para alguien. Me acabo de perder veinte minutos reaprendizaje esta lección :)

1

IO.popen

Ésta es otra buena opción:

IO.popen(['echo', 'a']) do |f| 
    f.read == "a\n" or raise 
end 
$?.exitstatus == 0 or raise 

Nada va a obtener una salida a su salida estándar.

http://www.ruby-doc.org/core-2.1.4/IO.html#method-c-popen

+0

TODO hace 'IO.popen ('cmd'). Close' ¿funciona también? http://stackoverflow.com/questions/1217351/io-popen-how-to-wait-for-process-to-finish#comment42139826_1236075 –

-1

Esto debería funcionar

system ls, STDOUT:'/dev/null' 
+0

Este es un argumento inválido, por lo que no hay idea de dónde viene esto. – Julik

1

me enfrentaba a esta pregunta, así ...

Tenga en cuenta que con rubí system llamadas, el comando UNIX que está intentando el uso puede ofrecer una opción "silenciosa", anulando la necesidad de suprimir por completo la salida del terminal.

Por ejemplo:

system 'curl -s "your_params_here"' 

suprimirá la salida que normalmente acompaña a una llamada rizo.

29

Si desea aprovechar la forma variadica de Kernel.system, que da un paso al costado de los muchos problemas de cotización con shells, puede usar el mismo options which Kernel.spawn accepts.

TL; DR - Uso :out => File::NULL para silenciar la salida de Kernel.system

Argumentos con caracteres especiales (espacios, etc.) puede causar problemas con la cáscara:

irb(main):001:0> filename_with_spaces = "foo bar.txt" 
=> "foo bar.txt" 

irb(main):002:0> system "ls -l #{filename_with_spaces}" 
ls: bar.txt: No such file or directory 
ls: foo: No such file or directory 
=> false 

Así que si están interpolando variables en una llamada al sistema, es más seguro proporcionar los argumentos por separado:

irb(main):003:0> system "ls", "-l", filename_with_spaces 
-rw-r--r-- 1 nobody nobody 9 Feb 1 16:53 foo bar.txt 
=> true 

Pero ahora tenemos un problema si queremos ocultar el resultado.

irb(main):004:0> system "ls", "-l", filename_with_spaces, "> /dev/null" 
ls: > /dev/null: No such file or directory 
-rw-r--r-- 1 nobody nobody 9 Feb 1 16:53 foo bar.txt 
=> false 

Podríamos cerrar la salida estándar utilizando la opción :out => :close:

irb(main):005:0> system "ls", "-l", filename_with_spaces, :out => :close 
=> true 

Sin embargo, esto podría causar problemas con ciertos comandos que puede tratar de conectar a la salida estándar. sistemas

irb(main):007:0> system "echo", "hi there", :out => File::NULL 
=> true 
+4

Esta es la respuesta correcta. –

+1

De esta respuesta pude deducir ': err =>' también. ¿Hay algo que signifique tanto 'out:' como ': err', entonces no tengo que escribir': out => File :: NULL,: err => File :: NULL'? – user137369

+0

Si observa la documentación de [kernel # spawn] (http://ruby-doc.org/core-2.3.0/Kernel.html#method-i-spawn), encontrará que puede hacer esto ' [: out,: err] => File :: NULL', así como muchas otras cosas. – Steve

0
  • definen null_device, se está operando dependent::

    irb(main):006:0> system "echo", "hi there", :out => :close 
    echo: write: Bad file descriptor 
    => false 
    

    Para solucionar esto, podemos volver a redirigir nuestra producción, utilizando File::NULL permanecer portátil ventanas 7 y más nuevos usan nul, mientras que * nix sistemas utiliza /dev/null

  • ejecución del comando
  • redirección es estándar y la salida de error a null_device
  • a continuación, utilizar el código de salida, o el método de acento grave como mentioned por @mikej para determinar la salida

de la siguiente manera:

null_device = Gem.win_platform? ? "/nul" : "/dev/null" 

do method 
    system "run command 1>#{null_device} 2>#{null_device} " 
    p ($? == 0) 
end 
Cuestiones relacionadas