Проверьте, существует ли файл на удаленном компьютере с пробелами в имени файла и / или пути

У меня простой скрипт bash; Я в основном хочу убедиться, что файл существует на удаленной машине. Я нашел множество примеров того, как это сделать, но недостающим компонентом является то, как это сделать с пробелами в пути и / или имени файла.

#!/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 

Таким образом, он терпит неудачу. Это приводит к синтаксической ошибке в условном выражении. Однако, если я изменю переменную FILE, чтобы сказать:

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

Скрипт работает (он находит файл, так как он есть).

Я выполнил следующие варианты моего условного выражения:

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

а также

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

Ни один из них не работает; Я знаю, что мне не хватает чего-то простого. Может ли кто-нибудь указать мне в правильном направлении?

Добавьте дополнительную пару кавычек, так что для локальной оболочки есть одна, а другая для удаленной оболочки – ssh .

 $ 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 

Вы хотите двойные кавычки снаружи, чтобы локальная оболочка расширила переменные перед ssh команды ssh . С одной кавычкой внутри, удаленная оболочка не будет расширять специальные символы дальше.

Если имя файла не содержит одиночные кавычки, то есть. В этом случае у вас возникнут проблемы.

Чтобы обойти это, вам понадобится что-то, что добавит необходимые escape-последовательности в строку. Некоторые системы имеют printf "%q" , новые версии Bash имеют расширение ${var@Q} которое должно делать что-то похожее.

 $ 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 

Я не уверен, что рекомендую это, но если ваш администратор сервера и / или их система / дистрибутив не усердно относятся к безопасности, вы можете злоупотреблять одним из (обычно) немногих envvars ssh который пройдет через:

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