---
layout: single
title:  "macOS 下的 __MACOSX 目录和 .DS_Store 文件"
date:   2023-05-15 08:00:00 +0800
categories: 操作系统
tags: [__MACOSX, .DS_Store, find, macOS, 知识扩展]
---

## .DS_Store 文件
.DS_Store 是 Desktop Services Store 的缩写。

.DS_Store 是 macOS 操作系统中隐藏的文件，它存储有关文件夹的元数据，例如文件夹中的文件位置、文件夹的显示选项和自定义图标等信息。这些元数据是用来帮助操作系统更快地显示文件夹中的内容，并记住用户的偏好设置。这些文件只是本地的，不会在网络文件共享时传输，因此不会影响其他操作系统用户。

## __MACOSX 目录

当你在 Mac 电脑上创建一个压缩文件时，系统会自动在压缩文件中添加一个名为 `__MACOSX` 的目录。该目录包含了 Mac 操作系统专有的一些文件，如 `.DS_Store` 等。这些文件不会对压缩文件的解压缩造成影响，但它们可能会在其他操作系统上解压缩时出现问题，例如在 Windows 上解压缩时可能会显示 `__MACOSX` 目录或 `.DS_Store` 文件。为了避免这种情况，你可以在创建压缩文件时选择不包含 Mac 专有文件，或者在解压缩时手动删除 `__MACOSX` 目录和 `.DS_Store` 文件。

## 删除 __MACOSX 目录和 .DS_Store 文件
### 方法一
```bash
find . -name '__MACOSX' -exec rm -rf {} \; -o -name '.DS_Store' -exec rm -f {} \;
```
这个命令使用 `find` 命令来查找当前目录中的所有 `__MACOSX` 目录和 `.DS_Store` 文件，并使用 `-exec` 参数来执行 `rm` 命令来删除它们。`-rf` 参数用于递归删除目录，`-f` 参数用于强制删除文件，`-o` 参数表示或者，将两个条件连接起来。

在 `find` 命令中，`-exec` 参数用于执行一个命令来处理查找到的文件或目录。`\;` 是 `-exec` 参数的终止符号，用于告诉 `find` 命令，在执行完 `-exec` 参数指定的命令后，结束这个 `-exec` 参数的执行。

因为在 shell 中，`;` 会被解释为命令的结束，所以需要在 `;` 前面加上 `\`，用于转义这个字符，以确保 `find` 命令能够正确的处理 `-exec` 参数。

在 `find` 命令中，`{}` 表示查找到的文件或目录的占位符。在 `-exec` 参数中，`{}` 会被替换成 `find` 命令查找到的每个文件或目录的路径。

例如，`find . -name '*.txt' -exec cat {} \;` 命令会查找当前目录及其子目录中所有扩展名为 `.txt` 的文件，并将每个文件的内容输出到终端。在这个命令中，`{}` 被替换成查找到的每个文件的路径。

### 方法二

```bash
find . -name '__MACOSX' -exec rm -rf {} ';' -o -name '.DS_Store' -exec rm -f {} ';'
```

### 方法三
```bash
find . -name '__MACOSX' -exec rm -rf {} + -o -name '.DS_Store' -delete
```

这个命令使用了 `-exec` 和 `-delete` 两种方式来删除 `__MACOSX` 目录和 `.DS_Store` 文件。`-exec` 参数使用了加号 `+`，用于将多个文件传递给一个单独的 `rm` 命令进行删除，而不是为每个文件都启动一个命令。`-delete` 参数用于直接删除 `.DS_Store` 文件。

注意，由于这个命令使用了 `-exec` 参数，所以在执行之前最好先测试一下，以确保它会删除你想要删除的文件，而不是误删其他文件。


## 知识扩展
### 在 shell 命令中，单引号和双引号的区别

1. 双引号中的变量会被解析，而单引号中的变量不会被解析。

例如，如果你有一个名为 `name` 的变量，且它的值为 `Tom`，则使用双引号和单引号输出这个变量的命令如下：

```
echo "Hello, $name!"  # 输出：Hello, Tom!
echo 'Hello, $name!'  # 输出：Hello, $name!
```

2. 双引号中可以使用转义字符，而单引号中无法使用转义字符。

例如，如果你想要输出 `Hello, "Tom"!`，则使用双引号和单引号输出这个字符串的命令如下：

```
echo "Hello, \"Tom\"!"  # 输出：Hello, "Tom"!
echo 'Hello, "Tom"!'    # 输出：Hello, "Tom"!
```

3. 双引号中可以包含单引号，而单引号中可以包含双引号。

例如，如果你想要输出 `Tom's diary`，则使用双引号和单引号输出这个字符串的命令如下：

```
echo "Tom's diary"  # 输出：Tom's diary
echo 'Tom'"'"'s diary'  # 输出：Tom's diary
```

在第二个命令中，使用了单引号和双引号组合的方式，将字符串 `Tom` 用单引号括起来，然后用双引号将两个字符串拼接在一起。由于单引号不能嵌套，因此需要使用转义字符 `'` 来表示一个单引号。
