Cite novamente:
if [ "$#" -eq 1 ] ; then
echo " Playing..." "$1"
sshpass -p "$passwd" ssh [email protected] -p "$port" "play '$1'"
else
echo " No Input audio file."
fi
O problema é que a primeira camada de aspas, o "$@"
, é expandido quando você executa o comando sshpass
. Então, quando você fizer login, iniciar o shell remoto e executar play
, você tem uma string sem aspas, então o seu script engasga com o espaço em branco. Ao colocá-lo em uma segunda camada de aspas, você garante que ele seja passado para o comando remoto.
Isso deve funcionar supondo que i) a máquina remota esteja executando sh
ou bash
ou um shell similar e ii) seus nomes de arquivos não contenham aspas simples. Para torná-lo realmente robusto, consulte Como executar um comando simples arbitrário sobre o ssh sem conhecer o shell de login do usuário remoto? .
Para citar corretamente uma cadeia arbitrária (ou mesmo uma lista de cadeias arbitrárias para que você possa passar mais de um argumento para play
) na sintaxe sh
, podemos usar essa função shquote()
mencionada lá:
shquote() {
LC_ALL=C awk -v q=\' -v b='\' '
BEGIN{
for (i=1; i<ARGC; i++) {
gsub(q, q b q q, ARGV[i])
printf "%s ", q ARGV[i] q
}
print ""
exit
}' "$@"
}
if [ "$#" -ge 1 ] ; then
echo " Playing..." "$@"
sshpass -p "$passwd" ssh [email protected] -p "$port" "play $(shquote "$@")"
else
echo " No Input audio file."
fi
Ele citaria Sgt. Pepper's lonely hearts club band.flac
as 'Sgt. Pepper'\''s lonely hearts club band.mp3'
, que está correto para sh
(e evil';reboot;: '.flac
as 'evil'\'';reboot;: '\''.flac'
em vez de reinicializar a máquina remota (você tem para executar essa% Comandoplay
como root
?)).