这周在编写自动部署脚本的过程遇到一个有趣的问题 —— 我把脚本打包成tgz文件,然后scp到被部署服务器上。解压之后发现多出来好些隐藏文件。比如下面的行1和行3:

$ ls ./init/letsencrypt/keys/
._0000_key-certbot.pem
0000_key-certbot.pem
._0000_key-letsencrypt.pem
0000_key-letsencrypt.pem

一开始我以为是系统自动生成的类似.DS_Store这样的系统文件,但ls -al看了下源目录,并没有发现踪迹。然后在本机(macOS)上把tgz文件tar zxvf出来,也没有发现这些文件的存在。

一头雾水。于是google「tar dot file」,找到了答案:

macOS自带的tar在打包过程中创建了这些隐藏文件,用于保存被打包文件的扩展属性,解包时会用隐藏文件中的数据重建扩展属性。ubuntu下的tar则不具备这个特性,会将隐藏文件原样解包出来。

可以通过ls -le@ *来查看扩展属性:

$ /bin/ls -le@ ./init/letsencrypt/keys/
total 56
-rw-------@ 1 Boxcounter  staff  1708 Nov 16 12:26 0000_key-certbot.pem
	com.apple.quarantine	  17
-rw-------@ 1 Boxcounter  staff  1704 Nov 16 12:26 0000_key-letsencrypt.pem
	com.apple.quarantine	  17
-rw-------@ 1 Boxcounter  staff  1704 Nov 16 12:26 0001_key-certbot.pem
	com.apple.quarantine	  17
-rw-------@ 1 Boxcounter  staff  1704 Nov 16 12:26 0001_key-letsencrypt.pem
	com.apple.quarantine	  17
-rw-------@ 1 Boxcounter  staff  1704 Nov 16 12:26 0002_key-certbot.pem
	com.apple.quarantine	  17
-rw-------@ 1 Boxcounter  staff  1704 Nov 16 12:26 0002_key-letsencrypt.pem
	com.apple.quarantine	  17
-rw-------@ 1 Boxcounter  staff  1704 Nov 16 12:26 0003_key-letsencrypt.pem
	com.apple.quarantine	  17

解决方法有两种:

  1. 设置环境变量COPYFILE_DISABLE禁用tar的这个行为:export COPYFILE_DISABLE=1
  2. 改用gnu tar:brew install gnu-tar --with-default-names

参考资料:Why do I get files like ._foo in my tarball on OS X?