通过带有双引号名称的变量scp复制文件

时间:2014-09-19 10:00:30

标签: bash scp

我正在尝试通过带有scp的ssh将我的项目从我的机器部署到我的测试服务器。我的问题是,在我部署当前目录中的所有内容之前,我必须跳过一些文件和目录。我的解决方案是,首先检查文件或目录是否符合某些条件,将其名称添加到变量中,当我的循环结束时,它将通过scp复制所有内容。然后,另一个我还不了解的问题是scp不想复制文件,如果它被包含在变量中的双引号“my-file”中。但我可能在名称中包含空格的文件。从命令行开始,它可以,但不是来自变量。

我的代码是

#...
FILES_TO_SEND=""
for file in *
do
    if test -d $file
    then
        if ! test $file = "nbproject"
        then
            FILES_TO_SEND="$FILES_TO_SEND \"$file\"" #or with this '$file'
        fi
    fi

    if test -f $file
    then
        if ! test $file = "changelog.html"
        then
            FILES_TO_SEND="$FILES_TO_SEND \"$file\"" #or with this '$file'
        fi
    fi
done

#--- Sending files ---#
scp -r ${FILES_TO_SEND} "${DEPLOY_SERVER}:${DEPLOY_TEST_ENV}"
#...

作为回应

"file1.html": No such file or directory
"file2.c": No such file or directory
"file3.sh": No such file or directory
...

PS:我想高效率,只需要在scp调用上只进行1次连接。服务器非常繁忙,我不想打开和关闭多次调用它的scp连接。

PS2:我无法安装rsync或类似的东西。我也不想每次部署时都通过sftp手动完成。

2 个答案:

答案 0 :(得分:2)

您可以这样做以生成“有效”代码:

FILES_TO_SEND=$(printf '%s "%q"' "$FILES_TO_SEND" "$file")

%q将执行引用空格,“等等

等字符的工作

例如:

$ printf '"%q"\n' 'Foo"Ba    '
"Foo\"Ba\ \ \ \ "

或者您可以尝试xargs

find '(' -type f -not -name 'changelog.html' ')' -or '(' -type d -not -path '*/nbproject/*' ')' -print0 | xargs -r0 scp -r "${DEPLOY_SERVER}:${DEPLOY_TEST_ENV}"

xargs在您的情况下会很好,但我找不到告诉scp "${DEPLOY_SERVER}:${DEPLOY_TEST_ENV}"是目的地而非来源的方法。

答案 1 :(得分:2)

bash(或任何其他具有类似支持的shell)中执行此操作的正确(且更简单)方法是使用数组而不是字符串来保存文件名。

#...
declare -a FILES_TO_SEND
for file in *; do
    if [[ -d $file ]]; then
        if ! [[ $file = "nbproject" ]]; then
            FILES_TO_SEND+=( "$file" )
        fi
    elif [[ -f $file ]]; then
        if ! [[ $file = "changelog.html" ]]; then
            FILES_TO_SEND+=( "$file" )
        fi
    fi
done

#--- Sending files ---#
scp -r "${FILES_TO_SEND[@]}" "${DEPLOY_SERVER}:${DEPLOY_TEST_ENV}"
#...

更简单:跳过显式的gather-files-in-a-loop方法,并使用匹配除禁用文件名和目录名之外的所有内容的模式。

shopt -s extglob
scp -r !(changelog.html|nbproject) "{$DEPLOY_SERVER}:${DEPLOY_TEST_ENV}"