我正在尝试通过带有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手动完成。
答案 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}"