检查远程计算机上是否存在文件名和/或路径中带有空格的文件

检查远程计算机上是否存在文件名和/或路径中带有空格的文件

我有一个简单的 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}" ]]

两者都不起作用;我知道我错过了一些简单的事情。有人可以指出我正确的方向吗?

答案1

添加一对额外的引号,这样一个用于本地 shell,一个用于偏僻的运行的外壳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

您希望在外部使用双引号,以便本地 shell 在ssh命令运行之前扩展变量。由于内部有单引号,远程 shell 不会进一步扩展特殊字符。

除非文件名包含单引号,否则。在这种情况下,你就会遇到麻烦。

要解决这个问题,您需要向字符串添加必要的转义符。有些系统有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

答案2

我不确定我是否推荐这样做,但除非您的服务器管理员和/或其系统/发行版热衷于安全性,否则您可以滥用(通常)少数几个环境变量之一ssh将通过:

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

相关内容