Mac mini(M4)配置及使用(2026)

Mac mini(M4)配置及使用(2026)

前言

最近趁着国补,入手了心心念念的Mac mini。之前一直想等等看春季发布会上能不能更新M5,但是发现本次没有。我是准备将其作为一台工作机,用来写代码,偶尔剪辑视频或者修图。其实一开始使用还挺不习惯,第一天配置的我头都大了,当天晚上都想着退货,但是发现用了国补激活了就不好推了。第二天把pycharm和Codex等都配置好之后,真香。


首次开机及激活

1.鼠标及键盘连接

因为Mac mini只有type-c和雷雳端口,没有USB接口,所以需要一个扩展坞(如果是Mac的键盘和鼠标则不需要,因为会优先检测自动连接)。如果是蓝牙键盘或鼠标,第一次使用,需要先用蓝牙接收器进行连接(至少我用的罗技是这样)。不过,建议还是先使用有线的键盘和鼠标,因为Mac mini没有触控板之类的,要设置连接蓝牙,至少需要一个有线鼠标。

先打开蓝牙,然后连接指定的设备(键盘或鼠标)

有一个需要注意的点,Mac的鼠标滚轮滚动方向跟windows是相反的,所以如果用windows上用的鼠标给Mac用需要做个调整。即在设置中,找到鼠标,然后关闭其【自然滚动】

2.配置

我是使用自己的iPhone扫描进行配置的,也可以选择作为一个全新的机器或者使用Mac进行配置。但是首次配置大概率会卡住,我等了大概30分钟左右。排除网速快慢的影响,应该就是卡住了,一直没进入页面,我就参照网上的帖子,长按电源键重启了,然后就可以打开了。

环境配置(Anconda安装)

参考:纯小白Mac安装Anaconda超详细攻略!

我个人觉得图形化界面安装也比较方便,符合Windows用户的习惯,也不需要特别配置什么

在 macOS 上安装_Anaconda 中文网

(纯小白教程)Mac OS中安装配置Anaconda及常用conda命令回顾


Node安装

因为会涉及前后端分离项目的开发,所以需要安装Node

参考:Mac 安装 node.js 及环境配置 以及 Node.js 安装指南(Mac 版本)

官方下载:nodejs.org/zh-cn/downlo

个人感觉Mac的环境安装还是比较简单的


Django安装

平时主要用Python安装,虽然Flask框架也很好,但是为了后续开发的可扩展性,还是使用Django

参考:详细介绍:Django 配置与安装完整指南

官方文档:如何安装 Django | Django 文档


数据库

SQLite:如何在PyCharm中优雅地查看SQLite数据库?针对专业版和社区版的完整方案

MySQL:

将下述代码复制并保存为setup_mysql_mac.sh

#!/usr/bin/env bash
set -euo pipefail

# =========================
# 参数区(只改这里)
# =========================
# [可改] 安装包:auto / mysql / mysql@8.0
MYSQL_FORMULA="${MYSQL_FORMULA:-auto}"

# [可改] 业务库配置(通用示例,不含项目标识)
DB_NAME="${DB_NAME:-app_meta}"
DB_USER="${DB_USER:-app_user}"
DB_HOST="${DB_HOST:-127.0.0.1}"
DB_PORT="${DB_PORT:-3306}"

# [敏感] 业务库密码:建议通过环境变量传入;留空则自动生成强密码
DB_PASSWORD="${DB_PASSWORD:-}"

# [可改] 输出配置文件路径(权限会设置为 600)
ENV_OUTPUT_FILE="${ENV_OUTPUT_FILE:-./db.mysql.local.env}"

# [可改] 是否修改 MySQL root 密码:0=否(默认),1=是
SET_ROOT_PASSWORD="${SET_ROOT_PASSWORD:-0}"
MYSQL_ROOT_OLD_PASSWORD="${MYSQL_ROOT_OLD_PASSWORD:-}"
MYSQL_ROOT_NEW_PASSWORD="${MYSQL_ROOT_NEW_PASSWORD:-}"

require_cmd() {
  command -v "$1" >/dev/null 2>&1 || { echo "[ERROR] 缺少命令: $1"; exit 1; }
}

validate_name() {
  local value="$1" label="$2"
  [[ "$value" =~ ^[A-Za-z0-9_]+$ ]] || { echo "[ERROR] ${label} 仅允许字母/数字/下划线"; exit 1; }
}

sql_escape() { printf "%s" "$1" | sed "s/'/''/g"; }
shell_escape_single_quote() { printf "%s" "$1" | sed "s/'/'\"'\"'/g"; }

generate_password() {
  if command -v openssl >/dev/null 2>&1; then
    openssl rand -base64 24 | tr -d '\n'
  else
    python3 - <<'PY'
import secrets, string
chars = string.ascii_letters + string.digits + "!@#$%^&*()-_=+"
print("".join(secrets.choice(chars) for _ in range(28)))
PY
  fi
}

prompt_secret_once() {
  local var="$1" tip="$2" v=""
  read -r -s -p "${tip}: " v; echo
  [[ -n "$v" ]] || { echo "[ERROR] 输入不能为空"; exit 1; }
  printf -v "$var" '%s' "$v"
}

prompt_secret_twice() {
  local var="$1" tip="$2" a="" b=""
  while true; do
    read -r -s -p "${tip}: " a; echo
    read -r -s -p "再次输入${tip}: " b; echo
    [[ -n "$a" ]] || { echo "[WARN] 不能为空"; continue; }
    [[ "$a" == "$b" ]] && break
    echo "[WARN] 两次输入不一致,请重试"
  done
  printf -v "$var" '%s' "$a"
}

pick_formula() {
  if [[ "$MYSQL_FORMULA" != "auto" ]]; then
    echo "$MYSQL_FORMULA"
    return
  fi
  if brew info --formula mysql@8.0 >/dev/null 2>&1; then
    echo "mysql@8.0"
  else
    echo "mysql"
  fi
}

wait_mysql_ready() {
  local mysqladmin_bin="$1"
  for _ in {1..60}; do
    "$mysqladmin_bin" ping --silent >/dev/null 2>&1 && return 0
    sleep 1
  done
  return 1
}

main() {
  require_cmd brew
  require_cmd sed
  require_cmd mktemp

  validate_name "$DB_NAME" "DB_NAME"
  validate_name "$DB_USER" "DB_USER"

  local auto_password=0
  if [[ -z "$DB_PASSWORD" ]]; then
    DB_PASSWORD="$(generate_password)"
    auto_password=1
  fi

  [[ "$SET_ROOT_PASSWORD" == "0" || "$SET_ROOT_PASSWORD" == "1" ]] || { echo "[ERROR] SET_ROOT_PASSWORD 只能是 0 或 1"; exit 1; }

  local formula
  formula="$(pick_formula)"

  brew list --versions "$formula" >/dev/null 2>&1 || brew install "$formula"
  brew services start "$formula" >/dev/null

  local prefix mysql_bin mysqladmin_bin
  prefix="$(brew --prefix "$formula")"
  mysql_bin="${prefix}/bin/mysql"
  mysqladmin_bin="${prefix}/bin/mysqladmin"

  wait_mysql_ready "$mysqladmin_bin" || { echo "[ERROR] MySQL 启动超时,请执行 brew services list 排查"; exit 1; }

  local root_login_file="" app_login_file=""
  cleanup() {
    [[ -n "$root_login_file" && -f "$root_login_file" ]] && rm -f "$root_login_file"
    [[ -n "$app_login_file" && -f "$app_login_file" ]] && rm -f "$app_login_file"
  }
  trap cleanup EXIT

  local -a root_cmd=("$mysql_bin" "-uroot")
  if ! "${root_cmd[@]}" -e "SELECT 1;" >/dev/null 2>&1; then
    if [[ -z "$MYSQL_ROOT_OLD_PASSWORD" ]]; then
      [[ -t 0 ]] || { echo "[ERROR] root 需要密码,请设置 MYSQL_ROOT_OLD_PASSWORD"; exit 1; }
      prompt_secret_once MYSQL_ROOT_OLD_PASSWORD "请输入当前 MySQL root 密码"
    fi

    root_login_file="$(mktemp)"
    chmod 600 "$root_login_file"
    cat > "$root_login_file" <<EOF
[client]
user=root
password=${MYSQL_ROOT_OLD_PASSWORD}
EOF
    root_cmd=("$mysql_bin" "--defaults-extra-file=${root_login_file}")
  fi

  "${root_cmd[@]}" -e "SELECT 1;" >/dev/null 2>&1 || { echo "[ERROR] root 登录失败"; exit 1; }

  if [[ "$SET_ROOT_PASSWORD" == "1" && -z "$MYSQL_ROOT_NEW_PASSWORD" ]]; then
    [[ -t 0 ]] || { echo "[ERROR] SET_ROOT_PASSWORD=1 时必须提供 MYSQL_ROOT_NEW_PASSWORD"; exit 1; }
    prompt_secret_twice MYSQL_ROOT_NEW_PASSWORD "请输入新的 MySQL root 密码"
  fi

  local sql_root_stmt=""
  if [[ "$SET_ROOT_PASSWORD" == "1" ]]; then
    sql_root_stmt="ALTER USER 'root'@'localhost' IDENTIFIED BY '$(sql_escape "$MYSQL_ROOT_NEW_PASSWORD")';"
  fi

  "${root_cmd[@]}" <<SQL
${sql_root_stmt}
CREATE DATABASE IF NOT EXISTS \`${DB_NAME}\` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER IF NOT EXISTS '$(sql_escape "$DB_USER")'@'127.0.0.1' IDENTIFIED BY '$(sql_escape "$DB_PASSWORD")';
CREATE USER IF NOT EXISTS '$(sql_escape "$DB_USER")'@'localhost' IDENTIFIED BY '$(sql_escape "$DB_PASSWORD")';
ALTER USER '$(sql_escape "$DB_USER")'@'127.0.0.1' IDENTIFIED BY '$(sql_escape "$DB_PASSWORD")';
ALTER USER '$(sql_escape "$DB_USER")'@'localhost' IDENTIFIED BY '$(sql_escape "$DB_PASSWORD")';
GRANT ALL PRIVILEGES ON \`${DB_NAME}\`.* TO '$(sql_escape "$DB_USER")'@'127.0.0.1';
GRANT ALL PRIVILEGES ON \`${DB_NAME}\`.* TO '$(sql_escape "$DB_USER")'@'localhost';
FLUSH PRIVILEGES;
SQL

  local escaped_pass
  escaped_pass="$(shell_escape_single_quote "$DB_PASSWORD")"
  cat > "$ENV_OUTPUT_FILE" <<EOF
# 自动生成(建议加入 .gitignore)
DB_ENGINE=mysql
DB_NAME=${DB_NAME}
DB_USER=${DB_USER}
DB_PASSWORD='${escaped_pass}'
DB_HOST=${DB_HOST}
DB_PORT=${DB_PORT}
EOF
  chmod 600 "$ENV_OUTPUT_FILE"

  app_login_file="$(mktemp)"
  chmod 600 "$app_login_file"
  cat > "$app_login_file" <<EOF
[client]
user=${DB_USER}
password=${DB_PASSWORD}
host=${DB_HOST}
port=${DB_PORT}
protocol=tcp
EOF
  "$mysql_bin" "--defaults-extra-file=${app_login_file}" -e "USE \`${DB_NAME}\`; SELECT 1;" >/dev/null

  echo "[OK] MySQL 已安装并初始化完成"
  echo "[OK] DB: ${DB_NAME}"
  echo "[OK] USER: ${DB_USER} (@localhost, @127.0.0.1)"
  echo "[OK] ENV: ${ENV_OUTPUT_FILE} (权限 600)"
  if [[ "$auto_password" == "1" ]]; then
    echo "[INFO] DB_PASSWORD 未显式传入,已自动生成并写入 ENV 文件"
  fi
  echo "[ACTION] 请将 ${ENV_OUTPUT_FILE} 加入 .gitignore"
}

main "$@"


运行

chmod +x setup_mysql_mac.sh
DB_PASSWORD='请替换为强密码' ./setup_mysql_mac.sh

说明:

  1. 这份脚本的目标是“一次执行完成安装 + 初始化”,无需拆多步命令。
  2. 脚本默认不输出明文密码,敏感信息只写入本地 ENV 文件,并自动设置权限为 600。
  3. 所有可调参数都集中在脚本顶部“参数区”,改动成本低。
  4. 默认行为是只创建业务库和业务账号,不修改 root 密码。若要修改 root,请设置 SET_ROOT_PASSWORD=1。
  5. 脚本支持 mysql 与 mysql@8.0,默认 auto 自动选择可用版本。
  6. 账号授权同时覆盖 localhost 和 127.0.0.1,避免本机常见连接差异。
  7. 数据库默认字符集是 utf8mb4,适配表情符号和多语言文本。

可修改参数(顶部参数区)

  1. MYSQL_FORMULA:安装包选择(auto / mysql / mysql@8.0)
  2. DB_NAME:数据库名
  3. DB_USER:业务账号
  4. DB_PASSWORD:业务账号密码(敏感)
  5. DB_HOST:数据库主机
  6. DB_PORT:数据库端口
  7. ENV_OUTPUT_FILE:连接配置文件输出路径
  8. SET_ROOT_PASSWORD:是否修改 root 密码(0/1)
  9. MYSQL_ROOT_OLD_PASSWORD:旧 root 密码(敏感)
  10. MYSQL_ROOT_NEW_PASSWORD:新 root 密码(敏感)

安全建议

  1. 不要把 ENV_OUTPUT_FILE 提交到 Git。
  2. 生产环境请使用密码管理器,不要把密码写进 shell 历史。
  3. 如果是公网部署,请额外配置防火墙和 MySQL 访问白名单。


Pycharm安装

去官网上下载安装包

下载 PyCharm:JetBrains 出品的用于数据科学和 Web 开发的 Python IDE


连接Windows server服务器

参考:如何从Mac连接到Windows Server?最新教程来了!

下载Windows App这个应用即可

连接共享盘

如果是在单位中,常常需要连接NAS,其实使用跟Windows差不多

参考:cn.mac-os.org/? 以及Mac 访问 Windows共享文件夹mac映射网络驱动器访问nas共享文件_mac映射nas-CSDN博客

前缀选择smb
ChatGPT安装

一开始我以为跟手机一样在应用商店中搜索然后安装,但是发现检索不到,不知道是不是因为账号所属地的问题。然后发现可以直接去官网上下载安装包。但是不知道是不是因为VPN不干净,一直显示让我关掉VPN再尝试下载(但如果关掉VPN国内是无法访问的)。切换了几个站点都是提示这个问题,最后我用了另一个平时不怎么用的设备登录网页,然后下载了安装包,再拷贝到mini中进行安装。

参考:还有不知道怎么在MAC上使用ChatGPT的桌面版的吗?

ChatGPT Mac下载实战:从安装到API调用的完整避坑指南

cursor-ide.com/blog/cha


Codex安装及使用

使用Codex进行代码编写 - perseus的文章 - 知乎

使用Codex进行代码编写(网页端、桌面端以及第三方API配置-2026)


Claude Code安装及使用

第三方API(MiMo):Claude Code CLI + MiMo(Mac Mini )配置


快捷键

参考:一文搞懂macOS怎么快速切换输入法/中英文/大小写

程序坞:macOS 全屏关闭以及如何调出「Dock(坞)」

如果用的是Mac键盘,我觉得没啥问题,用Windows通用键盘可能会不太习惯。

文件/目录地址复制:参考如何在 macOS 中复制文件和文件夹的路径


压缩及解压工具

参考:Mac解压缩软件测评,推荐解压 Rar, 7Z,winzip的解压神器,Mac 免费解压缩软件下这足够

我个人觉得系统自带的目前够用,解压就直接双击压缩包就能解压,压缩就右击目录


软件更新

在App Store更新Pages等软件时,提示无法更新App,重新登录账号也不行。

检索了一下资料,我感觉可能是我在京东上买的,之前怀疑被人用过了……。解决方案就是先在Finder中打开这个软件,然后卸载(移到废纸篓),然后再去App Store上下载软件即可

编辑于 2026-05-13 · 著作权归作者所有