Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用于复制文件和创建目录的Unix Shell脚本_Shell_Scripting_Directory_Mirroring - Fatal编程技术网

用于复制文件和创建目录的Unix Shell脚本

用于复制文件和创建目录的Unix Shell脚本,shell,scripting,directory,mirroring,Shell,Scripting,Directory,Mirroring,我有一个源目录,例如/my/source/directory/,还有一个目标目录,例如/my/dest/directory/,我想通过一些限制来镜像它 我想将符合find命令某些条件的文件(例如-ctime-2(不到2天)复制到dest目录以对其进行镜像 我想包括一些前缀,以便知道它来自哪里,例如/source/directory 我想用绝对路径来完成所有这些,所以它不依赖于我从哪个目录运行 我想没有cd命令也是一种很好的做法 如果子目录不存在,我希望创建它们 所以 我已经拼凑了下面的命令行

我有一个源目录,例如/my/source/directory/,还有一个目标目录,例如/my/dest/directory/,我想通过一些限制来镜像它

  • 我想将符合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
”非常强大和有效。有趣的是,GNU
cpio
有一个选项来处理来自“
find-print0
”的输出,即“
--null
”或其缩写形式“
-0
”。因此,使用GNU
find
和GNU
cpio
,safe命令是:

(cd /my; find source/directory -ctime -2 -print0 |
    cpio -pvdm0 /my/dest/directory)
注意:这不会覆盖备份目录下预先存在的文件。将
-u
添加到该命令的
cpio
命令中

类似地,GNU
tar
支持
--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 -)