scp
上传文件,但有时目标目录可能不存在。是否可以自动创建文件夹?如果是这样,怎么办?如果没有,我可以尝试其他替代方法吗?
#1 楼
这是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
一样,默认情况下,它将假定在远程计算机上存在与本地用户同名的用户。#2 楼
如果要复制一组文件,则不是。如果要复制目录及其下的所有内容,则可以。给定以下命令:如果directory
在~/the/target
上的host
中不存在~the/target
,则会创建它。但是,如果scp
不存在,则您可能会遇到问题-我不记得这种情况的确切结果,但要做好准备使预期的q4312079q失败。评论
scp:/ home / madmike / test_bin:没有这样的文件或目录。一旦缺少目标目录,这会破坏我的设置。在客户端上使用cygwin,在服务器上使用RHEL 6.9。你的设置是什么?
–MadMike
18-2-12在15:00
#3 楼
据我所知,scp
本身无法做到这一点,不。但是,您可以仅将ssh
移至目标计算机,创建目录,然后进行复制。 ssh user@host "mkdir -p /target/path/" &&
scp /path/to/source user@host:/target/path/
请注意,如果要复制整个目录,则不需要上述内容。例如,要将目录
~/foo
复制到远程主机,可以使用-r
(递归)标志:scp -r ~/foo/ user@host:~/
将在远程主机上创建目标目录
~/foo
。但是,它无法创建父目录。除非目标目录scp ~/foo user@host:~/bar/foo
存在,否则bar
将失败。无论如何,如果要复制单个文件,则-r
标志将无助于创建目标目录。评论
声明:“例如,要将目录〜/ foo复制到远程主机,可以使用-r(递归)标志:”,但是,下面的示例不使用-r标志/ option / argument / parameter (随便说一下):scp〜/ foo / user @ host:〜/。就是说,您的答案仍然获得18票赞成+1 :)
–WinEunuuchs2Unix
20年6月28日在18:59
@ WinEunuuchs2Unix感谢,已修复。
– terdon♦
20年6月29日在8:10
#4 楼
在通过btrfs
传输ssh
快照之前,我使用以下函数:check_remote_dir() {
printf "\ntesting remote directory: '' "
if ssh -p $PORT $ROOT@$REMOTE "[ ! -d ]"; then
printf "\nCreating: on $ROOT@$REMOTE\n"
ssh -p $PORT $ROOT@$REMOTE "mkdir -p "
else
printf "[OK]\n"
fi
}
只需在脚本中调用以下函数:
check_remote_dir /my/remote/path
评论
我做了几乎相同的事情,但是我不得不手动输入密码(出于安全原因),所以我最终至少要输入两次...
– Stefan Reich
18/12/14在12:25
#5 楼
是的你可以。根据scp的手册页:man scp
.....
-r递归地复制整个目录。请注意,scp遵循在树遍历中遇到的symâ
bolic链接。
....
评论
那将不会创建目标父目录。它可以将目录复制到现有位置。因此,如果远程bar /存在,则scp -r foo / u @ h:〜/ bar将创建bar / foo,但如果不存在则将失败。
– terdon♦
2015年3月30日13:32
它不会失败。它将foo内容复制到新目录/ bar。当然,名称已更改,这可能不是OP想要的。如果您想要的是在目标计算机中创建的新树结构,那么scp不会执行此任务,如果您想要从树中的某个分支复制树结构,则将创建该结构。
– Yomismo
2015年3月30日13:46
是的,但这仅在复制目录而不是文件时有效。 scp -r文件主机:〜/ bar /不会创建bar /。
– terdon♦
15 Mar 30 '15 at 13:57
#6 楼
当仅限于没有ssh的scp或sftp(由rssh使用)时,可以通过使用rsync复制空目录树然后复制文件来创建目录。这就是我放置公共ssh密钥的方式当ssh-copy-id不起作用并且.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中,再添加一个如果目标文件名相同,则在中间包含过滤器。
#7 楼
您可以将命令与mkdir命令链接在一起,然后引用您创建的文件夹:mkdir ~/new-folder/ && scp -P 22 <remote/url>:~/new-folder/
评论
(1)问题说“自动”。这似乎不是自动的。 (2)这似乎只是对terdon答案的细微差别。
– G-Man说“恢复莫妮卡”
19年1月22日,9:50
#8 楼
那么“ smart” scp + ssh mkdir怎么样?这是一个脚本,用于每个目录仅创建一次目标目录层次结构(而不是每次都盲目地
ssh mkdir -p
)。Rationale
我正在复制运动记录(视频文件)写入本地磁盘(事件驱动)时。
rsync
没有意义,因为进行完整目录比较没有意义-我正在转移每个事件一个文件。如果我将rsync限制为仅一个子目录或文件,那么它将无法创建完整的目标目录层次结构。scp
可以很好地工作,但是它不知道目标目录是否存在,而且我不想为每个文件运行ssh mkdir -p。解决方案
第一次需要通过ssh创建每个目标目录(第一次我们将要复制到其中。)
将目标目录名缓存在一个数组中,这样我们就不会在每次看到它时都不会再次调用它。每天清除此数组,以免它变大。
将文件保存起来。
示例代码:
ssh mkdir
典型输出,说明“智能” mkdir行为:
#!/bin/bash
TARGETHOST="some.hostname"
TARGETPATH="/data/backups/MOTION/"
ensure_dir() {
if [ "$TODAY" != "$(date +%D)" ] ; then
CREATED=() # reset array daily and first time so it won't get huge
TODAY=$(date +%D)
fi
if [[ ! " ${CREATED[@]} " =~ " " ]]; then
# create dir
echo "Creating remote directory: "
ssh $TARGETHOST "mkdir -p ${TARGETPATH}"
CREATED+=("")
fi
}
# This line is specific to my use case, watching a directory for new files:
inotifywait -mr --format '%w %f' -e close_write --exclude '.jpg' /data/MOTION/ | while read filedir filename ; do
RELDIR=$(echo $filedir | sed 's|/data/MOTION/||')
ensure_dir "$RELDIR"
echo "Copying '$filename' from '${filedir}' to '${RELDIR}'"
scp -r -p "${filedir}${filename}" "${TARGETHOST}:${TARGETPATH}${RELDIR}${filename}"
done
评论
我正在使用Mac OSX,是否需要在本地和远程都安装rsync?
– AGamePlayer
15年3月30日在13:27
搜索了rsync的文档页面,未找到如何使用ssh-key登录。我不想使用用户名/密码登录
– AGamePlayer
2015年3月30日13:28
@AwQiruiGuo:Mac OS X附带了rsync。是的,您也确实需要在远程端进行rsync,就像使用scp一样。至于SSH密钥,rsync实际上是在默认的-e ssh下面使用SSH,因此,如果您设置了与scp一起使用的密钥,它们也将对rsync起作用。
–沃伦·杨(Warren Young)
15年3月30日在13:29
@WarrenYoung -r没有区别。您描述的方案仅在复制目录并且目标父目录存在的情况下才有效。因此,rsync foo / u @ h:〜/将创建目标目录foo,而rsync foo / u @ h:〜/ bar /将不创建目标目录bar。只有在bar /存在的情况下,才会创建bar / foo。无论如何,OP都在上传文件,即使在这种情况下,它也仅适用于整个目录。
– terdon♦
15年3月30日在13:29
是的,我也一直在玩。似乎指定文件名也会使其失败。因此,如果foo /不存在,则rsync文件host:/ foo / file失败,但是rsync文件host:/ foo /创建目录并将文件放置在其中。奇怪。无论如何,您说的没错,基本方案可行,我将收回我的不赞成票。
– terdon♦
15年3月30日在13:55