用于复制文件和创建目录的Unix Shell脚本
我有一个源目录,例如/my/source/directory/,还有一个目标目录,例如/my/dest/directory/,我想通过一些限制来镜像它用于复制文件和创建目录的Unix Shell脚本,shell,scripting,directory,mirroring,Shell,Scripting,Directory,Mirroring,我有一个源目录,例如/my/source/directory/,还有一个目标目录,例如/my/dest/directory/,我想通过一些限制来镜像它 我想将符合find命令某些条件的文件(例如-ctime-2(不到2天)复制到dest目录以对其进行镜像 我想包括一些前缀,以便知道它来自哪里,例如/source/directory 我想用绝对路径来完成所有这些,所以它不依赖于我从哪个目录运行 我想没有cd命令也是一种很好的做法 如果子目录不存在,我希望创建它们 所以 我已经拼凑了下面的命令行
- 我想将符合find命令某些条件的文件(例如-ctime-2(不到2天)复制到dest目录以对其进行镜像
- 我想包括一些前缀,以便知道它来自哪里,例如/source/directory
- 我想用绝对路径来完成所有这些,所以它不依赖于我从哪个目录运行
- 我想没有cd命令也是一种很好的做法
- 如果子目录不存在,我希望创建它们
find /my/source/directory -ctime -2 -type f -printf "%P\n" | xargs -IFILE rsync -avR /my/./source/directory/FILE /my/dest/directory/
如果您认为我应该自己添加此命令行作为答案,请发表评论,我不想贪图名誉。您可以使用复制传递模式-p尝试cpio。我通常将其与覆盖全部(-u)、创建目录(-d)和维护修改时间(-m)一起使用 请记住,find应该生成相对路径名,这不符合绝对路径条件。这种感冒当然可以用cd“解决”,你也不喜欢cd(为什么不呢?)
括号将生成一个子shell,并将状态更改(即目录开关)保持在本地。您还可以定义一个小程序来抽象掉“丑陋”。另一种方法是使用tar, (cd$源;tar cf-)|(cd$目标;tar xf-) 编辑: 啊,我错过了关于我的一点。我相信大多数tar实现都会保留mtime,但如果保留ctime是关键,那么cpio确实是唯一的方法
此外,一些tar实现(GNU tar就是其中之一)可以根据atime和mtime选择要包含的文件,尽管看起来不是ctime。如果您使用find always-print0并通过xargs-0将输出传输;几乎总是这样。如果使用find的默认换行符输出,则名称中带有空格的第一个文件将阻塞脚本 我同意所有其他的海报-使用cpio或焦油如果可以的话。它会做你想做的,省去麻烦
#!/bin/sh
SRC=/my/source/directory
DST=/my/dest/directory
for i in $(find $SRC -ctime -2 -type f) ; do
SUBDST=$DST$(dirname $i)
mkdir -p $SUBDST
cp -p $i $SUBDST
done
我想,既然您想包括“它来自何处”,那么您将使用不同的源目录。只需将SRC=/my/source/directory替换为SRC=$1,即可修改此脚本,将source dir作为参数
编辑:删除多余的if语句
当文件名有空格时不起作用。这与一个(封闭的)问题非常相似:。我给出的答案引用了其他答案中提到的“
find | cpio
”解决方案(减去时间标准,但这是“相似”和“相同”之间的区别),并概述了使用GNU“tar”的解决方案
时间
当我在Solaris上测试时,GNU tar和(Solaris)cpio都不能保留ctime设置;事实上,我不确定是否有办法做到这一点。例如,touch
命令可以设置atime或mtime或两者,但不能设置ctime。utime()
系统调用也只接受mtime或atime值;它不适合我。因此,我相信,如果您找到一个保留ctime的解决方案,该解决方案可能是特定于平台的。(奇怪的例子:入侵磁盘设备并编辑inode中的数据-不可移植,需要提升权限。)不过,重读这个问题,我发现“保存ctime”不是要求的一部分(phew);这只是文件是否被复制的标准
chdir
我认为“cd
”操作是必要的,但它们可以完全本地化到脚本或命令行,尽管如此,如所引用的问题和下面的命令行所示,第二个命令行假定为GNU tar
(cd /my; find source/directory -ctime -2 | cpio -pvdm /my/dest/directory)
(cd /my; find source/directory -ctime -2 | tar -cf - -F - ) |
(cd /my/dest/directory; tar -xf -)
如果不使用chdir()
(又称cd
),则需要专门的工具或选项来处理动态路径名操作
带空格、换行符等的名称
Adam Hawes指出,GNU特有的“find-print0
”和“xargs-0
”非常强大和有效。有趣的是,GNUcpio
有一个选项来处理来自“find-print0
”的输出,即“--null
”或其缩写形式“-0
”。因此,使用GNUfind
和GNUcpio
,safe命令是:
(cd /my; find source/directory -ctime -2 -print0 |
cpio -pvdm0 /my/dest/directory)
注意:这不会覆盖备份目录下预先存在的文件。将-u
添加到该命令的cpio
命令中
类似地,GNUtar
支持--null
(显然没有-0
缩写形式),也可以使用:
(cd /my; find source/directory -ctime -2 -print0 | tar -cf - -F - --null ) |
(cd /my/dest/directory; tar -xf -)
GNU使用空终止符处理文件名是非常聪明的,也是一项有价值的创新(尽管我是最近才意识到这一点的,幸亏如此;它在GNU tar中已经存在了至少十年)。/usr/bin/sh
用于复制具有相同目录结构的文件的脚本“
echo“请输入源目录的完整路径(以/开头,以/结尾):
读斯帕斯
echo“请输入目标位置的完整路径(以/开头,以/结尾):
读dpath
si=echo“$spath”| awk-F/'{print NF-1}'
对于中的fname,请查找$spath-类型f-打印
做
cdir=
echo$fname | awk-F/'{for(i='$si';我请给出你的答案。这有什么难看的?它不使用空终止符,所以它会在名称中包含空格和换行符的文件上出现错误?我总是对脚本中的CD感到有点不舒服。可能是因为太紧张了,但我总是喜欢在任何上下文中工作并且对状态没有影响的命令。我我不是一个shell脚本大师,这可能是不合理的,这就是为什么我把它放在括号里,这将产生一个子shell
(cd /my; find source/directory -ctime -2 | cpio -pvdm /my/dest/directory)
(cd /my; find source/directory -ctime -2 | tar -cf - -F - ) |
(cd /my/dest/directory; tar -xf -)
(cd /my; find source/directory -ctime -2 -print0 |
cpio -pvdm0 /my/dest/directory)
(cd /my; find source/directory -ctime -2 -print0 | tar -cf - -F - --null ) |
(cd /my/dest/directory; tar -xf -)