我目前正在编写一个脚本,它将对一组数据库执行备份,压缩它们,加密它们,将它们传输到单独的存储计算机,并验证文件是否成功。我可以创建备份并执行标准压缩和加密,以便可以安全地传输并存储在辅助位置。此后,ssh
用于验证目标计算机上是否存在目录或强制创建该目录,然后用于scp
传输文件,最后ssh
用于验证另一端是否存在该文件。
这在过去效果很好,但是对脚本进行了更改,以在文件名中包含时间戳(除了现有的日期戳),并且:
文件名中该时间戳中的字符导致传输在传输scp
和下面ssh
来测试该文件的存在。
DATE
目前,我正在脚本顶部创建一个变量并将其设置为以下内容: $(date --date=today +%FT%H:%M:%S%z)
,这会在正确的位置生成日期戳ISO 8601格式。这可以很好地创建数据库转储(使用 创建的 postgres 转储pg_dump
)以及使用压缩gzip
和加密openssl
。其中每一个都会生成一个新文件,所有名称的格式为HOSTNAME.DATABASE-dump-DATE.EXTENSION
.
当向文件名提供日期而没有时间,因此没有字符时:
,它工作得很好。我现在收到的具体错误是有:
字符的以下代码段($1
指提供给脚本的参数,包含要备份的数据库的名称,$DATE是上面定义的):
scp -P PORT "$(hostname).$1-dump-$DATE.backup.gz.aes" USER@HOST:"/backups/$(hostname)/"
此操作失败并出现错误ssh: could not resolve hostname HOSTNAME.DATABASE-dump-2015-07-31T13: Name or service not known
。
ssh HOST -p PORT <<"HERE"
if test -f /backups/$(hostname)/$(hostname).$1-dump-$DATE.backup.gz.aes;
then echo "File exists";
else echo "Transfer failed";
fi
HERE
这失败了Pseudo-terminal will not be allocated because stdin is not a terminal
。使用-t
会产生相同的错误,并且使用-t -t
(来自在堆栈溢出导致关于伪终端的兔子洞)不允许之后给出的命令流过,这可能是我错过的关于它实际作用的事情。
我想避免使用需要在计算机上安装的任何其他软件(运行 Ubuntu 14.04 和最新的 Postgresql for DB)。请告诉我是否有任何方法scp/ssh
可以正确处理这些文件。
答案1
scp -P PORT "$(hostname).$1-dump-$DATE.backup.gz.aes" USER@HOST:"/backups/$(hostname)/"
scp 支持将文件从一台远程主机复制到另一台远程主机,执行此操作的语法是使用“主机名:文件名”语法指定源和目标:
scp srchost:/src/file desthost:/dest/file
您的源文件名称中包含冒号,因此 scp 尝试将其解析为远程文件的主机名和文件名。
您可以通过确保参数的第一个冒号之前有一个“/”来防止 scp 将源文件名参数视为远程文件名。主机名中不能包含“/”,并且 scp 在第一个“/”之后停止在命令行参数中查找冒号。这应该有效:
scp -P PORT "./$(hostname).$1-dump-$DATE.backup.gz.aes" USER@HOST:"/backups/$(hostname)/"
^^-- Prepend a ref to the current directory