终端中使用cp -r命令拷贝带软连接的文件,导致软连接文件出错。

Macbook M1-MaxPro电脑在终端中使用cp -r命令拷贝带软连接的文件,导致软连接文件出错。

从oracle官网下载https://download.oracle.com/java/17/latest/jdk-17_macos-aarch64_bin.tar.gz (sha256 )的jdk.tar.gz包,解压之后将jdk-17.0.1.jdk复制到/Users/lijingli/jdk目录下,添加~/.bash_profile文件,加入JAVA_HOME目录,source

~/.bash_profile文件,然后再命令行中执行java -version查看jdk版本,出现jdk已损坏,无法打开。


但是使用访达讲解压好的文件夹拷贝过去的时候,就可以正常使用,但是在命令行中使用cp命令拷贝过去才会不可用,具体命令:cp -r jdk-17.0.1.jdk /Users/lijingli/jdk


使用工具对比访达中拷贝过去的文件夹,和命令行拷贝过去的文件夹对比发现存在不一致情况。


这个问题对于有用户界面的笔记本电脑还好说,在访达里拷贝就是了,但是如果将来M1芯片用到了Apple的服务器系统上,在命令行中操作压缩文件,那不是要gg了,将来有了M1芯片的苹果服务器一定要验证一下这个问题他们解决了没有,否则可能导致脚本不能正常运行。



[经过版主编辑]

MacBook Pro 14″, macOS 12.0

发布日期 2022年1月10日 下午11:07

回复
问题被标记为 排名最靠前的回复

发布日期 2022年1月15日 上午2:37

刚才查了一下标准,之前写的要改了,但在最后保留之前写的,以作对比,可以看出关键态度的转变过程。


大家知道 macOS 的基于 UNIX 核心的,具体说的 BSD,而且从2007 年以来它是被认证为符合 UNIX 03 的操作系统的。而 cp 命令是 UNIX 系统核心命令之一,那么要看 cp 命令是否应该支持 -r 选项,那么就要看规范是如何规定的了。


目前来说,UNIX 规范是由 open group 管理的,规范可以从它的官网的图书库下载,网址https://publications.opengroup.org/,只不过需要注册一下。我下载和参考的是“The Single UNIX® Specification: The Authorized Guide to Version 4”。没有旧版本相互对照,实在也是没有时间和精力,谁要是有的话,可以从不同版本中找到 cp 命令的规范的异同,能更全面的看出各个版本岁时间的变化。


就我下载的版本来说,它明确说作废了的 -r 被移除了。也就是说 cp 命令可以不支持 -r 选项了。参见下面的截图:


所以,我的建议是,应该改用 -R,最好是使用 -a。

从这里我也是学到了不少的东西,也是多谢 willWang 的执著追求。


-----------------------------------下面是之前写的-------------------------------------------------

如果需要 macOS 应该把 -r 实现为 与 -R 一样的,一方面可以填写 feedback;另一方面如果有开发者账号,在该账号中提交系统改进会更有效。


在 Linux man cp 中 -r 与 -R 是相同的, 在 Mac 上的实现 -R 是没问题的的。Mac 上 man cp 中说的 -r 是“ Historic versions of the cp utility had a -r option. ..... its use is strongly discouraged”,也就是 -r 这个选项强烈不建议使用。说明中有了说明和注释,说明它开发者是有意为之而不是忽视。对于一个公认特殊作用的功能,它的实现有瑕疵,那肯定是个 bug。但是像这种的就不好说是不是 bug 了,那么,提出改进意见是否被采纳,就看开发者了。从另外一个角度考虑,如果以后都使用 -R 参数,自己的脚本其实更通用不是。在我个人来说,一般都是遇到问题,看看说明,然后遵循本系统的规范,当然这样的负面问题是很难发现 bug。


另外,就如同 Linux 中 -d 其实就是 -pP,在 Mac 中就没有 -d,有 -p 和 -P。Linux 中在 -a 的说明中,使用的是"same as -dR --preserve=all" ,其中不是 -r 而是 -R,可能这个也会说明一点点问题,当然并不是什么太大的论点支撑,只是说细节。


macOS 系统的确有其自身的特点,毕竟它与任何 Linux 系统只能算是远房亲戚。还有好多命令方面与 Linux 相左。这种差异化在其实在 Linux 的不同发行版中也是存在的。比如 rpm 流派和 deb 流派的,而 Mac 上最流行的是 homebrew等。


最后,为了能够保证复制后的数据保持原样,个人实践最好是用 -a(也就是-pPR),而非单单的 -R。


[经过版主编辑]





回复量: 10
问题被标记为 排名最靠前的回复

2022年1月15日 上午2:37 回应 willWang_1024

刚才查了一下标准,之前写的要改了,但在最后保留之前写的,以作对比,可以看出关键态度的转变过程。


大家知道 macOS 的基于 UNIX 核心的,具体说的 BSD,而且从2007 年以来它是被认证为符合 UNIX 03 的操作系统的。而 cp 命令是 UNIX 系统核心命令之一,那么要看 cp 命令是否应该支持 -r 选项,那么就要看规范是如何规定的了。


目前来说,UNIX 规范是由 open group 管理的,规范可以从它的官网的图书库下载,网址https://publications.opengroup.org/,只不过需要注册一下。我下载和参考的是“The Single UNIX® Specification: The Authorized Guide to Version 4”。没有旧版本相互对照,实在也是没有时间和精力,谁要是有的话,可以从不同版本中找到 cp 命令的规范的异同,能更全面的看出各个版本岁时间的变化。


就我下载的版本来说,它明确说作废了的 -r 被移除了。也就是说 cp 命令可以不支持 -r 选项了。参见下面的截图:


所以,我的建议是,应该改用 -R,最好是使用 -a。

从这里我也是学到了不少的东西,也是多谢 willWang 的执著追求。


-----------------------------------下面是之前写的-------------------------------------------------

如果需要 macOS 应该把 -r 实现为 与 -R 一样的,一方面可以填写 feedback;另一方面如果有开发者账号,在该账号中提交系统改进会更有效。


在 Linux man cp 中 -r 与 -R 是相同的, 在 Mac 上的实现 -R 是没问题的的。Mac 上 man cp 中说的 -r 是“ Historic versions of the cp utility had a -r option. ..... its use is strongly discouraged”,也就是 -r 这个选项强烈不建议使用。说明中有了说明和注释,说明它开发者是有意为之而不是忽视。对于一个公认特殊作用的功能,它的实现有瑕疵,那肯定是个 bug。但是像这种的就不好说是不是 bug 了,那么,提出改进意见是否被采纳,就看开发者了。从另外一个角度考虑,如果以后都使用 -R 参数,自己的脚本其实更通用不是。在我个人来说,一般都是遇到问题,看看说明,然后遵循本系统的规范,当然这样的负面问题是很难发现 bug。


另外,就如同 Linux 中 -d 其实就是 -pP,在 Mac 中就没有 -d,有 -p 和 -P。Linux 中在 -a 的说明中,使用的是"same as -dR --preserve=all" ,其中不是 -r 而是 -R,可能这个也会说明一点点问题,当然并不是什么太大的论点支撑,只是说细节。


macOS 系统的确有其自身的特点,毕竟它与任何 Linux 系统只能算是远房亲戚。还有好多命令方面与 Linux 相左。这种差异化在其实在 Linux 的不同发行版中也是存在的。比如 rpm 流派和 deb 流派的,而 Mac 上最流行的是 homebrew等。


最后,为了能够保证复制后的数据保持原样,个人实践最好是用 -a(也就是-pPR),而非单单的 -R。


[经过版主编辑]





2022年1月15日 下午9:07 回应 tonyfromcalgary

非常感谢tonyfromcalgary的回复,让我学到了很多。以前不管在windows系统还是在ubuntu系统、Centos系统、kaliLinux、raspberryPi系统都是用cp -r复制一个文件夹,突然在Mac系统上使用导致问题,就理所当然的认为是Mac系统加M1芯片的问题了,这次才注意到原来cp -r在标准中cp 命令已经可以不支持 -r 选项了,只是Mac系统+M1芯片导致一个很基本的命令错误,确实让人诧异。替代方案有很多:可以直接在访达中用鼠标拷贝,可以下载后让mac归档然后使用留下的tar文件在处理,可以使用cp -R等,只要别使用脚本中经常使用的wget http://***.tar.gz 然后直接tar -zxvf ***.tar.gz 再cp -r ***.tar.gz就行,尽管目前百分之九十九的脚本都是这么写的。

苹果在线技术支持,不支持终端命令的问题,feedBack已经提交了问题,也没有人处理。看来只能看市场,看广大果粉来是否接受让一个错误的命令存在于Mac+M1设备上了。

2022年1月11日 下午9:51 回应 willWang_1024

其一,是否可以尝试直接解压到你的目录,比如

tar -zxvf myfile.tar.gz -C /Users/lijingli/jdk


其二,Mac 的一些命令有其特殊的地方。对于 cp 命令,man cp 中的“COMPATIBILITY”一项。我一般使用 -a 选项,对于你的这个没有尝试。你可以再看看-H, -L, -P和-R等各个选项。


以上都没有测试你的情况,只是说说自己的发现。

2022年1月15日 下午9:56 回应 willWang_1024

不用谢。你得出“一个错误的命令存在于Mac”上的结论有待商榷。


IEEE Std 1003 是 POSIX在 IEEE 中给其定义规范的标准。ISO 中叫 ISO/IEC 9945。Linux基本上逐步实现了POSIX兼容,但对正式的POSIX认证感兴趣的不多。其实在前面提到的 The Open Group 中提到的 Austin Group 其实就是 IEEE 中计算机社区的团体,这两者之间互相参照,所以它们两者的标准基本上的互容的。


刚才查了一下 IEEE 1003.1的 2007年的一个版本,暂时以这个版本来说,有限的时间内只有这个版本可用。相信在其它前后的版本中也会找到类似的解释。如下图。其中特也提到的 BSD 系统,解释了为什么使用了-R,而-r 的确是历史原因的,而且也提到-r 是在标准中被移除了,但是在实际的系统中,都被时限为与-R 相同的功能。


所以说,在 Linux 世界中,对于 -r 标准与 Mac的是相同的。Mac 中的解释没有错,Mac 对于标准的执行没有错,因为它是被认证的,应该执行规范。而之所以在其它系统中还在使用,只不过他们把两个等同看待而已,他们自己不想认证不必执行规范。但是它们确实根据规范的变动把传统的 -r 改为与 -R 相同了。

要想向新系统和更多平台兼容,应该使用标准中的 -R,而不是因为“原来好好的,以前没有问题,别人都没问题,就你出问题,你就是你的问题,你应该改”。需要改的恰恰是我们自己的习惯,适应并依从标准,改变自己的习惯,路走得更长远。


当然了,要是能把规范改为 -r 是必须必的了,那么就更好了,这个过程至少可以写进回忆录中了。




[经过版主编辑]

2022年1月17日 上午6:56 回应 tonyfromcalgary

多谢tonyfromcalgary的回复,看来是apple走在了标准的前面,做了第一个吃螃蟹的人,是其他系统还没有按照标准执行,是广大用户还没有习惯使用-R作为复制文件夹的参数,仍然在使用-r作为复制文件夹的参数了。

2021款MacBook pro是我第一款苹果笔记本,不太方便在MacBook Intel版本上测试。今天找朋友帮忙测试了一下,确实在intel芯片的mac电脑上cp -r也同样会导致软连接文件出错。

本来想再买一台MAC pro,既然Intel芯片的Mac系统存在同样的问题,那就在等等吧,别买来了,ssh远程过去脚本执行后报错就麻烦了。能反馈的渠道我都已经反馈了,看苹果官方什么时候能给出官方答复吧,多谢您的热情回复。

这个主题已被系统或社区团队关闭。 你可以为你认为有帮助的任何帖子投票,也可以在社区中搜索其他答案。

终端中使用cp -r命令拷贝带软连接的文件,导致软连接文件出错。

欢迎来到 Apple 支持社区
Apple 客户在其产品方面互相帮助的论坛。使用您的 Apple 帐户开始畅游其中吧!!