Verifique se existe um arquivo em uma máquina remota com espaços no nome do arquivo e / ou caminho

3

Eu tenho um script simples; Eu basicamente quero ter certeza de que o arquivo existe em uma máquina remota. Eu encontrei vários exemplos de como fazer isso, mas o componente ausente é como fazer isso com espaços no caminho e / ou nome de arquivo sendo avaliado.

#!/bin/bash

HOST=server.local
DIR=/foo/bar
FILE="Foo Bar File With Spaces"


if ssh $HOST [[ -f ${DIR}/${FILE} ]]
then
   echo "The file exists"
else
   echo "The file doesn't exist."
fi

Então, isso falha. Isso me causa um erro de sintaxe na expressão condicional. No entanto, se eu alterar a variável FILE para dizer:

FILE="Foo\ Bar\ File\ With\ Spaces"

O script funciona (encontra o arquivo desde que ele está lá).

Eu tentei as seguintes variações para minha expressão condicional:

if ssh $HOST [[ -f "${DIR}/${FILE}" ]]

e

if ssh $HOST [[ -f "${DIR}"/"${FILE}" ]]

Nenhum dos quais funciona; Eu sei que estou sentindo falta de algo simples. Alguém pode me indicar a direção certa?

    
por Allan 19.10.2016 / 17:18

2 respostas

8

Adicione um par extra de aspas, portanto, há uma para o shell local e outra para o shell remoto , em que ssh é executado.

$ dir=/tmp; file="foo bar"; 
$ ssh somewhere ls -l "'$dir/$file'"
-rw-r--r-- 1 foo foo 4194304 Oct 19 18:05 /tmp/foo bar
$ ssh somewhere [[ -f  "'$dir/$file'" ]] ; echo $?
0

Você deseja as aspas duplas no exterior para que o shell local expanda as variáveis antes que o comando ssh seja executado. Com uma aspa simples no interior, o shell remoto não expandirá mais os caracteres especiais.

A menos que o nome do arquivo contenha aspas simples, isto é. Nesse caso, você terá problemas.

Para contornar isso, você precisará de algo que adicione as fugas necessárias à string. Alguns sistemas têm printf "%q" , novas versões do Bash têm a ${var@Q} expansão que deve fazer algo semelhante semelhante.

$ dir=/tmp; file="\$foo' bar"
$ fullpath="$(printf "%q" "$dir/$file")"
$ ssh somewhere ls -l "$fullpath"
-rw-r--r-- 1 foo foo 0 Oct 19 18:45 /tmp/$foo' bar
    
por 19.10.2016 / 17:37
-1

Não tenho certeza se recomendo isso, mas a menos que seu administrador de servidor e / ou seu sistema / distribuição seja zeloso com a segurança, você poderia abusar de um dos (normalmente) poucos envalars ssh passará por:

export LC_MESSAGES='path/to/file with spaces'
if ssh $host '[ -f "$LC_MESSAGES" ]' ; then ...
    
por 20.10.2016 / 09:50