Problema com caminho de passagem contendo espaços e colchetes

3

Eu uso o Thunar File Explorer e passo o caminho e o nome do arquivo para uma audioplay de script. audioplay roda o comando play no meu android via ssh que toca uma música.

script de audioplay :: cat audioplay

if [ $# -eq 1 ] ; then
echo "   Playing..." "$@"
sshpass -p $passwd  ssh [email protected] -p $port  play "$@"
else
 echo "  No Input audio file."
fi

reproduzir script no meu android :: cat play

    #!/data/bin/bash
    # Avoid linker errors due to libOpenSLES.so:
    echo "File ::" "$@"
    LD_LIBRARY_PATH= exec /data/bin/blob/play-audio "$@"

O problema é que o caminho não é passado corretamente para executar o comando por ssh. O caminho com espaços múltiplos torna-se espaço único e os colchetes criam um erro de sintaxe.

Exemplo:

Para o arquivo 18. Warriors.flac presente em /sdcard/Music/Imagine Dragons - Smoke Mirrors -Deluxe Edition-2015

O caminho enviado para a audioplay está correto: /sdcard/Music/Imagine Dragons - Smoke Mirrors -Deluxe Edition-2015/18. Warriors.flac

Mas o caminho recebido pelo script de jogo está errado: /sdcard/Music/Imagine Dragons - Smoke Mirrors -Deluxe Edition-2015/18. Warriors.flac Espaços múltiplos são transformados em espaço único. Por quê?

Em seguida, o principal binário play-audio obtém apenas o caminho /sdcard/Music/Imagine até o primeiro espaço apenas.

Exemplo 2 ::

Eu tentei com o arquivo com colchetes: 44. Go Tell Aunt Rhody -Resident Evil- (Short Version).flac O caminho recebido pelo script de audioplay está correto: /sdcard/Music/44. Go Tell Aunt Rhody -Resident Evil- (Short Version).flac Mas eu recebo este erro :: sh: syntax error: '(' unexpected

Eu tentei passar $@ $* "$@" e "$*" . Mas nenhum deles funcionou para mim.

    
por jonny789 26.09.2017 / 17:26

1 resposta

2

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 ?)).

    
por 26.09.2017 / 17:33