POSIXly,您将pax
在读+写模式下使用以下-l
选项:
pax -rwlpe -s /A/B/ dirA .
(-pe
保留被复制文件的所有可能的属性(在这种情况下,只有目录),如GNU cp
的-a
一样)。
现在,尽管是标准命令,但该命令并不一定非常可移植。
首先,许多基于GNU / Linux的系统pax
默认情况下不包括(即使这是非可选的POSIX实用程序)。
然后,许多错误和与某些实现不符导致该代码出现许多问题。
- 由于存在错误,与结合使用
pax
时,Solaris 10 (至少)不起作用。由于某种原因,它似乎将替换应用于原始路径和复制路径。因此,在上面,它将尝试做一些代替。-rwl
-s
link("dirB/file", "dirB/file")
link("dirA/file", "dirB/file")
- 在FreeBSD上,
pax
不会为符号链接类型的文件创建硬链接(POSIX允许的行为)。不仅如此,但它也适用于替代的符号链接的目标(行为不通过POSIX允许的)。因此,举例来说,如果有一个foo -> AA
符号链接dirA
,它将成为foo -> BA
在dirB
。
另外,如果要执行相同的操作,但要使用内容存储在$src
和中的任意文件路径$dst
,则必须认识到pax -rwl -- "$src" "$dst"
创建$src
inside 的完整目录结构$dst
(必须存在并且是目录),这一点很重要。例如,如果$src
为foo/bar
,则$dst/foo/bar
创建。
相反,如果您想$dst
成为的副本$src
,最简单的方法可能是:
absolute_dst=$(umask 077 && mkdir -p -- "$dst" && cd -P -- "$dst" && pwd -P) &&
(cd -P -- "$src" && pax -rwlpe . "$absolute_dst")
(这也可以解决上述大多数问题,但是如果$dst
以换行符结尾的绝对路径会失败)。
现在,在没有的GNU / Linux系统上这将无济于事pax
。
有趣的是,它pax
是由POSIX创建的,用于合并tar
and cpio
命令的功能。
cpio
与POSIX发明相反,它是一个历史悠久的 Unix命令(始于1977年),并且还有一个GNU实现(不是pax
一个)。因此,即使它不再是标准命令(尽管它是在SUSv2中使用的),它仍然非常常见,并且通常可以依靠一组核心功能。
相当于pax -rwl
将cpio -pl
。然而:
cpio
接受stdin上输入文件的列表而不是参数(以换行符分隔,这表示不支持带有换行符的文件名)
- 所有文件都必须指定的(一般你给它的输出
find
(find
并且cpio
由同一人共同开发))。
- 元数据不保留(某些
cpio
实现具有保留一些但不能移植的选项)。
因此cpio
:
absolute_dst=$(umask 077 && mkdir -p -- "$dst" && cd -P -- "$dst" && pwd -P) &&
(cd -P -- "$src" && find . | cpio -pl "$absolute_dst")
pax
,在FreeBSD上,likecp -a
不会硬链接符号链接。