【问题标题】:scp a folder to a remote system keeping the directory layoutscp 一个文件夹到远程系统,保持目录布局
【发布时间】:2023-03-13 22:41:02
【问题描述】:

我有一个包含数百个嵌套子文件夹的大型目录树。我只需要将 4 个文件夹及其内容复制到远程系统,但我需要将目标文件夹结构保持不变。

例如

./test/sub1/subsub1/hello.txt
./test/sub1/subsub2/hello2.txt    
./test/sub2/hello3.txt

我想将 ./test/sub1/subsub1/* 复制到 user@system:~/test/sub1/subsub1/* 等目标,但我不想复制 subsub2 或 sub2。

我尝试过如下使用 scp:

scp -r ./test/sub1/subsub1 me@my-system:~/test/sub1/subsub1

结果:scp: /test/sub1/subsub1: No such file or directory

我也试过了:

scp -r ./test/sub1/subsub1 me@my-system:~/test

这可行,但会将所有文件转储到一个目录中。不维护 /test/sub1/subsub1 目录结构。

如何复制文件夹,同时保持其结构?

【问题讨论】:

  • 懒人版:tar -cf myfile.tar ./test/sub1/subsub1; scp myfile me@mysystem:~; echo 'tar -xf myfile.tar && rm myfile.ta' | ssh me@mysystem
  • 使用存档还有一个优势,即一个大文件的数据传输速度比数百个小文件(如果您有数百个小文件)要快。
  • 非常真实和伟大的单线。我试了一下,确实生成了 tar 文件,但是得到一个“不会分配伪终端,因为 stdin 不是终端错误”。

标签: linux scp


【解决方案1】:

您需要一个两次通过的解决方案。首先,确保目标目录存在于远程主机上:

ssh me@my-system 'mkdir -p ~/test/sub1/subsub1' 

然后,您可以复制文件。我建议使用rsync 而不是scp,因为它是为同步目录而设计的。示例用法:

rsync -r -e ssh ./test/sub1/subsub1/ me@my-system:~/test/sub1/subsub1

-e 标志接受远程 shell 来执行传输。 rsync 的尾部斜杠非常重要,因此请确保您的斜杠与上面的示例相匹配。

【讨论】:

  • 谢谢,几乎可以工作,但我有一个小问题。使用您给出的第一个示例进行复制会在目标计算机上创建 /test/subsub1。 test 和 subsub1 之间的 sub1 丢失。同样使用 rsync,如果我指定完整路径,则会出现 no such directory 错误。
  • 我认为如果您在第一个示例源目录的末尾添加 / 将解决您的最后一个问题。
  • 很遗憾没有。放置斜杠会获取 /test/sub1/subsub1 的内容并将其转储到目标系统上的 /test 中,同时删除 /subsub1。
  • 嘿克里斯,我更新了答案。由于您没有同步整个目录树,这是 rsync 最典型的用例,因此您必须确保远程目录存在。
  • 您好,感谢您的跟进和修改;我刚刚进入并尝试更新。不幸的是,我无法一次性创建深层目录路径。 ssh me@mine 'mkdir ~/test' 通过。 ssh me@mine 'mkdir ~/test/sub1' 失败并显示消息:“mkdir: cannot create directory '/home/me/test/sub1': No such file or directory。我现在得到的意见是没有办法在单个命令中直接创建多文件夹深层目录?看起来很傻。为帮助干杯
【解决方案2】:

使用-R (--relative) 选项进行rsync 以保留目录结构。看看:

https://serverfault.com/questions/39522/how-to-keep-the-full-path-with-rsync

这是一个例子:

[localbox] tree test
test
└── sub1
    └── subsub1
        ├── a
        ├── b
        ├── c
        ├── d
        ├── e
        └── f


 [localbox] rsync -avR test/sub1/subsub1 me@my-system:dest_path
 sending incremental file list
 created directory dest_path
 test/
 test/sub1/
 test/sub1/subsub1/
 test/sub1/subsub1/a
 test/sub1/subsub1/b
 test/sub1/subsub1/c
 test/sub1/subsub1/d
 test/sub1/subsub1/e
 test/sub1/subsub1/f

 sent 406 bytes  received 185 bytes  394.00 bytes/sec
 total size is 0  speedup is 0.00

 [localbox] ssh me@my-system
 [my-system] tree dest_path
 dest_path
 `-- test
    `-- sub1
        `-- subsub1
            |-- a
            |-- b
            |-- c
            |-- d
            |-- e
            `-- f

  3 directories, 6 files

以下是从 rsync 手册页中截取的:

-R, --relative

使用相对路径。这意味着命令行上指定的完整路径名被发送到服务器,而不仅仅是 文件名的最后部分。这在您 想同时发送几个不同的目录。为了 例如,如果您使用此命令:

     rsync -av /foo/bar/baz.c remote:/tmp/

... 这将在远程机器上的 /tmp/ 中创建一个名为 baz.c 的文件。如果你使用了

     rsync -avR /foo/bar/baz.c remote:/tmp/

然后将在远程计算机上创建一个名为 /tmp/foo/bar/baz.c 的文件,并保留其完整路径。这些额外的路径 元素被称为“隐含目录”(即“foo”和 上面示例中的“foo/bar”目录)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-05
    • 2011-04-11
    • 1970-01-01
    • 2022-08-22
    相关资源
    最近更新 更多