我想使用scp
上传文件,但有时目标目录可能不存在。
是否可以自动创建文件夹?如果是这样,怎么办?如果没有,我可以尝试其他替代方法吗?
我想使用scp
上传文件,但有时目标目录可能不存在。
是否可以自动创建文件夹?如果是这样,怎么办?如果没有,我可以尝试其他替代方法吗?
Answers:
这是rsync
可以做的许多事情之一。
如果您使用的rsync
是过去几年发布的版本,¹其基本命令语法类似于scp
:
$ rsync -r local-dir remote-machine:path
这会将local-source
其内容复制到$HOME/path/local-dir
远程计算机上,从而创建所需的任何目录。³
rsync
确实有一些限制可能会影响它在您的特定情况下是否有效。例如,它不会创建多个级别的丢失的远程目录;它只会在遥控器上最多创建一个丢失的级别。您可以通过在rsync
命令之前添加类似以下内容来轻松解决此问题:
$ ssh remote-host 'mkdir -p foo/bar/qux'
$HOME/foo/bar/qux
如果它不存在,那将创建树。它不会抱怨,或者如果它做任何事情坏就已经存在。
rsync
有时还有其他令人惊讶的行为。基本上,您是在要求它弄清楚您要复制的内容,其猜测可能与您的假设不符。试试看。如果它的行为不符合您的预期,并且您看不到原因,请发布有关本地和远程目录设置的更多详细信息,并提供您尝试的命令。
脚注:
在rsync
2.6.0 之前(2004年1月1日),它要求该-e ssh
标志使其行为类似,scp
因为它默认为过时的RSH协议。
scp
并rsync
共享一些标志,但是只有一点点重叠。
当SSH
用作传输协议时,rsync
使用相同的默认值。因此,就像一样scp
,默认情况下,它将假定在远程计算机上有一个与本地用户同名的用户。
rsync
的文档页面,未找到如何使用ssh-key登录。我不想使用用户名/密码登录
rsync
。是的,rsync
就像一样,您也确实需要远程scp
。至于SSH密钥,rsync
实际上是在默认情况下使用SSH -e ssh
,因此,如果您设置了与一起使用的密钥scp
,它们也将适用rsync
。
-r
没有区别。您描述的方案仅在复制目录并且目标父目录存在的情况下才有效。因此,rsync foo/ u@h:~/
将创建目标目录,foo
但rsync foo/ u@h:~/bar/
不会创建目标目录bar
。bar/foo
只有bar/
存在时才会创建。无论如何,OP都在上传文件,即使在这种情况下,它也仅适用于整个目录。
rsync file host:/foo/file
失败,如果foo/
不存在,但rsync file host:/foo/
创建目录和地方file
在里面。奇怪。无论如何,您说的没错,基本方案可行,我将收回我的不赞成票。
如果要复制一组文件,则不是。如果要复制目录及其下的所有内容,则可以。给出以下命令:
$ scp -pr /source/directory user@host:the/target/directory
如果on directory
中不存在,则会创建它。但是,如果不存在,您可能会遇到问题-我不记得这种情况的确切结果,但是要为失败做好准备。~/the/target
host
~the/target
scp
scp: /home/madmike/test_bin: No such file or directory
一旦目标目录丢失,这将破坏我的设置。在客户端上使用cygwin,在服务器上使用RHEL 6.9。你的设置是什么?
据我所知,scp
它本身不能做到这一点,不。但是,您可以仅ssh
到目标计算机,创建目录,然后复制。就像是:
ssh user@host "mkdir -p /target/path/" &&
scp /path/to/source user@host:/target/path/
请注意,如果要复制整个目录,则不需要上面的内容。例如,要将目录复制~/foo
到远程主机,可以使用-r
(递归)标志:
scp ~/foo/ user@host:~/
这将~/foo
在远程主机上创建目标目录。但是,它无法创建父目录。scp ~/foo user@host:~/bar/foo
除非目标目录bar
存在,否则将失败。无论如何,-r
如果您要复制单个文件,则该标志将无助于创建目标目录。
是的你可以。根据scp的手册页:
男子SCP
.....
-r递归复制整个目录。请注意,scp遵循在树遍历中遇到的符号链接。
....
scp -r foo/ u@h:~/bar
将创建bar/foo
,bar/
但如果不存在则将失败。
foo
内容复制到新目录/bar
。当然,名称已更改,这可能不是OP想要的。如果您想要的是在目标计算机中创建的新树结构,scp
则将无法执行该工作;如果您想要的是从树中的某个分支复制树结构,则将创建该结构。
scp -r file host:~/bar/
不会创建bar/
。
在转移btrfs
快照之前,我使用以下功能ssh
:
check_remote_dir() {
printf "\ntesting remote directory: '$1' "
if ssh -p $PORT $ROOT@$REMOTE "[ ! -d $1 ]"; then
printf "\nCreating: $1 on $ROOT@$REMOTE\n"
ssh -p $PORT $ROOT@$REMOTE "mkdir -p $1"
else
printf "[OK]\n"
fi
}
只需使用以下命令在脚本中调用该函数:
check_remote_dir /my/remote/path
当限制为仅scp或sftp且没有可用的ssh时(由rssh启用),可以通过使用rsync复制空目录树然后复制文件来创建目录。
当ssh-copy-id不起作用并且.ssh目录不存在时,这就是我将公用ssh密钥放置到远程主机的方式:
rsync -e 'ssh -p22' -av -f"+ */" -f"- *" ~/.ssh backup@1.2.3.4:~/
scp -P22 ~/.ssh/id_rsa.pub backup@1.2.3.4:~/.ssh/authorized_keys
如果目标文件名相同,则可以将此命令组合为一个rsync,并在中间添加一个include过滤器。