2011-08-03 8 views
26

Muy bien, este me está volviendo loca:rubí escapar argumento ARGV o cadena como argumento para shell de comandos

`ls #{"/media/music/Miles Davis"}` 

falla debido al espacio entre "Miles" y "Davis"

Di escribo un rubí script y un usuario pasa la ruta del archivo como un argumento. ¿Cómo puedo escapar y alimentar a un comando de salida? Sí, sí, lo sé, los bombardeos deben evitarse. Pero este es un ejemplo artificial, todavía necesito esto.

Haría system("ls", ARGV[0]), pero no devuelve la salida stdout de ls como una cadena, que es lo que hacen bien los backticks.

¿Cómo se puede escapar lo que inserte en un contenedor?

Respuesta

51

Uso require 'shellwords' y Shellwords.escape, que fijará este tipo de cosas para usted:

http://apidock.com/ruby/Shellwords/shellescape

+2

Excelente! ¡Gracias! No sabía sobre ese módulo. – ulver

+0

También puede usar el atajo 'String # shellescape', como este: ' ls # {"/ media/music/Miles Davis" .shellescape} ' – cgenco

-2

Las comillas dobles también funciona:

`ls "#{'/media/music/Miles Davis'}"` 

o

`ls "#{ARGV[0]}"` 
+0

No haga eso. Considere: 'a = '-l" | wc -l # "';' '' ls "# {a}" '' – Mike

+0

Esto funciona para espacios, pero falla de su cadena tiene un '" ', '$', u otros caracteres. – Carpetsmoker

6

St Además de crear cadenas de shell siempre que sea posible, es un vector fino para la ejecución de código arbitrario.

En este caso, se puede usar popen, lo que hace el escape para usted:

IO.popen(['printf', 'a b']) do |f| 
    var = f.read 
end 
+1

Esto debería tener más votos ascendentes. popen también permite imprimir una respuesta transmitida de manera bastante conveniente, por ejemplo, while (line = f.gets) {puts line}. – vise

+0

Aquí hay una versión aún más compacta: 'IO.popen ([" file "," --brief "," --mime-type ", untrustworthy_input], en:: close, err:: close) .read' – aidan

Cuestiones relacionadas