bash 递归使用 scp 但不包括某些文件夹

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15121337/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 23:23:43  来源:igfitidea点击:

recursively use scp but excluding some folders

bashscp

提问by mahmood

Assume there are some folders with these structures

假设有一些具有这些结构的文件夹

/bench1/1cpu/p_0/image/
/bench1/1cpu/p_0/fl_1/
/bench1/1cpu/p_0/fl_1/
/bench1/1cpu/p_0/fl_1/
/bench1/1cpu/p_0/fl_1/
/bench1/1cpu/p_1/image/
/bench1/1cpu/p_1/fl_1/
/bench1/1cpu/p_1/fl_1/
/bench1/1cpu/p_1/fl_1/
/bench1/1cpu/p_1/fl_1/
/bench1/2cpu/p_0/image/
/bench1/2cpu/p_0/fl_1/
/bench1/2cpu/p_0/fl_1/
/bench1/2cpu/p_0/fl_1/
/bench1/2cpu/p_0/fl_1/
/bench1/2cpu/p_1/image/
/bench1/2cpu/p_1/fl_1/
/bench1/2cpu/p_1/fl_1/
/bench1/2cpu/p_1/fl_1/
/bench1/2cpu/p_1/fl_1/
....

What I want to do is to scpthe following folders

我想要做的是scp以下文件夹

/bench1/1cpu/p_0/image/
/bench1/1cpu/p_1/image/
/bench1/2cpu/p_0/image/
/bench1/2cpu/p_1/image/

As you can see I want to recursively use scpbut excluding all folders that name "fl_X". It seems that scp has not such option.

如您所见,我想递归使用scp但排除所有名为“fl_X”的文件夹。似乎 scp 没有这样的选择。

UPDATEscp has not such feature. Instead I use the following command

UPDATEscp 没有这样的功能。相反,我使用以下命令

 rsync -av --exclude 'fl_*' user@server:/my/dir

But it doesn't work. It only transfers the list of folders!! something like ls -R

但它不起作用。它只传输文件夹列表!!就像是ls -R

采纳答案by jxh

Although scpsupports recursive directory copying with the -roption, it does not support filtering of the files. There are several ways to accomplish your task, but I would probably rely on find, xargs, tar, and sshinstead of scp.

尽管scp-r选项支持递归目录复制,但它不支持文件过滤。有几种方法来完成你的任务,但我可能会依靠findxargstar和,ssh而不是scp

find . -type d -wholename '*bench*/image' \
| xargs tar cf - \
| ssh user@remote tar xf - -C /my/dir

The rsyncsolution can be made to work, but you are missing some arguments. rsyncalso needs the rswitch to recurse into subdirectories. Also, if you want the same security of scp, you need to do the transfer under ssh. Something like:

rsync解决方案可以起作用,但您缺少一些参数。rsync还需要r切换到递归到子目录。此外,如果您想要与 相同的安全性scp,则需要在 下进行传输ssh。就像是:

rsync -avr -e "ssh -l user" --exclude 'fl_*' ./bench* remote:/my/dir

回答by Captain Barbossa

You can specify GLOBIGNOREand use the pattern *

您可以指定GLOBIGNORE和使用模式*

GLOBIGNORE='ignore1:ignore2' scp -r source/* remoteurl:remoteDir

You may wish to have general rules which you combine or override by using export GLOBIGNORE, but for ad-hoc usage simply the above will do. The :character is used as delimiter for multiple values.

您可能希望拥有可以通过 using 组合或覆盖的一般规则export GLOBIGNORE,但对于临时使用,只需以上操作即可。该:字符用作多个值的分隔符。

回答by Marian

Assuming the simplest option (installing rsync on the remote host) isn't feasible, you can use sshfsto mount the remote locally, and rsyncfrom the mount directory. That way you can use all the options rsync offers, for example --exclude.

假设最简单的选项(在远程主机上安装 rsync)不可行,您可以使用sshfs在本地挂载远程,并从挂载目录使用rsync。这样你就可以使用 rsync 提供的所有选项,例如--exclude.

Something like this should do:

这样的事情应该做:

sshfs user@server: sshfsdir
rsync --recursive --exclude=whatever sshfsdir/path/on/server /where/to/store

Note that the effectiveness of rsync (only transferring changes, not everything) doesn't apply here. This is because for that to work, rsync must read every file's contents to see what has changed. However, as rsync runs only on one host, the whole file must be transferred there (by sshfs). Excluded files should not be transferred, however.

请注意,rsync 的有效性(仅传输更改,而不是所有内容)不适用于此处。这是因为要使其工作,rsync 必须读取每个文件的内容以查看更改的内容。但是,由于 rsync 仅在一台主机上运行,​​因此必须将整个文件传输到那里(通过 sshfs)。但是,不应传输排除的文件。

回答by Ofer Eliassaf

If you use a pem file to authenticate u can use the following command (which will exclude files with something extension):

如果您使用 pem 文件进行身份验证,您可以使用以下命令(这将排除带有某些扩展名的文件):

rsync -Lavz -e "ssh -i <full-path-to-pem> -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" --exclude "*.something" --progress <path inside local host> <user>@<host>:<path inside remote host>

The -L means follow links (copy files not links). Use full path to your pem file and not relative.

-L 表示跟随链接(复制文件而不是链接)。使用 pem 文件的完整路径而不是相对路径。

Using sshfs is not recommended since it works slowly. Also, the combination of find and scp that was presented above is also a bad idea since it will open a ssh session per file which is too expensive.

不推荐使用 sshfs,因为它运行缓慢。此外,上面介绍的 find 和 scp 的组合也是一个坏主意,因为它会为每个文件打开一个 ssh 会话,这太昂贵了。

回答by WackGet

You can use extended globbing as in the example below:

您可以使用扩展通配符,如下例所示:

#Enable extglob
shopt -s extglob

cp -rv !(./excludeme/*.jpg) /var/destination

回答by Fady Ibrahim

This one works fine for me as the directories structure is not important for me.

这个对我来说很好用,因为目录结构对我来说并不重要。

scp -r USER@HOSTNAME:~/bench1/?cpu/p_?/image/ .

Assuming /bench1is in the home directory of the current user. Also, change USER and HOSTNAME to the real values.

假设/bench1在当前用户的主目录中。此外,将 USER 和 HOSTNAME 更改为实际值。