2013-07-04 7 views
17

Sto tentando di avviare mplayer. Il mio nome file contiene spazi e questi dovrebbero essere sfuggiti. Questo è il codice che sto usando:Come evitare le stringhe per il terminale in Ruby?

@player_pid = fork do 
    exec "/usr/bin/mplayer #{song.file}" 
end 

dove #{song.file} contiene un percorso come "/home/example/music/01 - a song.mp3". Come posso sfuggire questa variabile correttamente (e possibili altri caratteri strani che il titolo può contenere) in modo che il terminale accetti il ​​mio comando?

risposta

29

Shellwords dovrebbe funzionare per voi :)

exec "/usr/bin/mplayer %s" % Shellwords.escape(song.file) 

In rubino 1.9.x, sembra che si deve in primo luogo require

require "shellwords" 

Ma in Ruby 2.0.x, Non ho dovuto richiederlo esplicitamente.

+0

Grazie che funziona! – xorinzor

15

Non utilizzare mai il modulo "riga di comando singola" di exec, che consente di aprire tutti i soliti problemi di quotatura e di iniezione e lancia inutilmente una shell. Dal fine manual:

exec (CmdName, arg1, ...)

nome del comando e uno o più argomenti (senza guscio)

Così, invece di gingillarsi con citando e scappando e cosa no, basta usare la versione senza shell:

exec '/usr/bin/mplayer', song.file 

e bypassare la shell compl etely. Allo stesso modo per system.

+1

Il problema qui non è che ognuno abbia il percorso '/ usr/bin/mplayer', quindi potrebbe essere necessario fare riferimento a un meccanismo per individuare l'eseguibile. Naturalmente, se questo programma è solo per il tuo consumo, dovrebbe andare bene. – vgoff

+0

Anche questa soluzione funziona davvero, ma dato che la mia domanda riguardava in realtà come scappare da una stringa, lascerò la mia risposta invariata, grazie comunque. – xorinzor

+0

@vgoff: Sapete che 'exec' cercherà il' PATH', giusto? E se provate a usare '/ usr/bin/mplayer' con una delle due forme di' exec' e non avete 'mplayer' in'/usr/bin', allora, naturalmente, fallirà in entrambi i casi. –