#!/usr/bin/env bashset -eecho "=============================="echo " Linux Workstation Setup (Interactive Final)"echo "=============================="confirm() {read -rp "$1 (y/n): " ans [[ "$ans" == "y" || "$ans" == "Y" ]]}=========================================================1. ZSH + OH-MY-ZSH=========================================================if confirm "[1/5] 安装 zsh + oh-my-zsh + 设置默认 shell"; thensudo apt update sudo apt install -y zsh curl git xdg-user-dirs wget if [ ! -d "$HOME/.oh-my-zsh" ]; then RUNZSH=no CHSH=no KEEP_ZSHRC=yes \ sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" fi if [ "$SHELL" != "$(which zsh)" ]; then chsh -s "$(which zsh)" || true fi echo "✔ ZSH 完成"elseecho "✘ 跳过 ZSH"fi=========================================================2. PROXY (proxy on/off)=========================================================if confirm "[2/5] 配置 proxy (proxy on / proxy off)"; thenread -rp "请输入代理地址 (如 http://192.168.1.78:4780): " PROXY_URL if [ -n "$PROXY_URL" ]; then cat > ~/.proxy.zsh << EOF=========================Proxy CLI=========================PROXY_URL="$PROXY_URL"proxy() {case "\$1" in on) export http_proxy="\$PROXY_URL" export https_proxy="\$PROXY_URL" export all_proxy="\$PROXY_URL" export no_proxy="localhost,127.0.0.1,::1" git config --global http.proxy "\$PROXY_URL" git config --global https.proxy "\$PROXY_URL" echo "[proxy] ON -> \$PROXY_URL" ;; off) unset http_proxy https_proxy all_proxy no_proxy git config --global --unset http.proxy 2>/dev/null || true git config --global --unset https.proxy 2>/dev/null || true echo "[proxy] OFF" ;; *) echo "Usage:" echo " proxy on" echo " proxy off" ;; esac}EOF if ! grep -q "proxy.zsh" ~/.zshrc; then echo "source ~/.proxy.zsh" >> ~/.zshrc fi echo "✔ Proxy 完成" else echo "✘ 未输入 proxy，跳过" fielseecho "✘ 跳过 proxy"fiif confirm "[3/5] 切换英文用户目录 + 迁移 + 删除旧中文目录"; thensudo apt install -y xdg-user-dirs rsync # ===================================================== # 1. 强制切换为英文 XDG # ===================================================== LANG=en_US.UTF-8 xdg-user-dirs-update --force echo "已切换为英文用户目录" # ===================================================== # 2. 中文 -> 英文映射 # ===================================================== declare -A MAP=( ["桌面"]="Desktop" ["下载"]="Downloads" ["文档"]="Documents" ["图片"]="Pictures" ["音乐"]="Music" ["视频"]="Videos" ["公共"]="Public" ["模板"]="Templates" ) echo "开始迁移文件..." for zh in "${!MAP[@]}"; do en="${MAP[$zh]}" src="$HOME/$zh" dst="$HOME/$en" if [ -d "$src" ]; then mkdir -p "$dst" echo "迁移: $src -> $dst" # 安全复制（不覆盖已有文件） rsync -a --ignore-existing "$src/" "$dst/" echo "完成: $zh → $en" fi done echo "迁移完成，开始删除旧目录..." # ===================================================== # 3. 删除旧中文目录（关键步骤） # ===================================================== for zh in "${!MAP[@]}"; do src="$HOME/$zh" if [ -d "$src" ]; then echo "删除: $src" rm -rf "$src" fi done echo "====================================" echo "完成：中文目录已迁移并删除" echo "建议重新登录会话" echo "====================================" elseecho "跳过目录迁移"fi=========================================================4. GO (国内镜像 + fallback)=========================================================if confirm "[4/5] 安装 Golang（国内镜像）"; thenGO_VERSION="1.22.5" GO_TAR="go${GO_VERSION}.linux-amd64.tar.gz" cd /tmp echo "尝试国内镜像下载..." if ! wget -q https://mirrors.aliyun.com/golang/$GO_TAR; then echo "阿里云失败，切换官方源..." wget -q https://go.dev/dl/$GO_TAR fi sudo rm -rf /usr/local/go sudo tar -C /usr/local -xzf $GO_TAR if ! grep -q "/usr/local/go/bin" ~/.zshrc; then cat >> ~/.zshrc << 'EOF' Goexport PATH=$PATH:/usr/local/go/bin:$HOME/go/binEOFfi echo "✔ Go 完成"elseecho "✘ 跳过 Go"fi=========================================================5. NVM + NODE=========================================================if confirm "[5/5] 安装 nvm + node"; thenexport NVM_DIR="$HOME/.nvm" if [ ! -d "$NVM_DIR" ]; then curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash fi if ! grep -q "nvm.sh" ~/.zshrc; then cat >> ~/.zshrc << 'EOF' NVMexport NVM_DIR="$HOME/.nvm"[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"EOFfi echo "✔ NVM 完成"elseecho "✘ 跳过 NVM"fi=========================================================echo "=============================="echo "全部完成"echo "请执行：source ~/.zshrc"echo "=============================="
Linux + Ghostty + fcitx5 + Rime 全流程踩坑指南(含搜狗迁移 & Lua 问题)
我把 Linux 输入法从搜狗换成 Rime，顺手踩了几个坑最近换了个终端，用的是 Ghostty，然后发现一个很现实的问题：
原文 https://www.bilibili.com/opus/890449778240913446安装后直接一波# !/bin/bash rm /opt/sogoupinyin/files/lib/qt5/lib/libQt5Core.so.5 ln -s /usr/lib/x86_64-linux-gnu/libQt5Core.so.5 /opt/sogoupinyin/files/lib/qt5/lib/libQt5Core.so.5 rm /opt/sogoupinyin/files/lib/qt5/lib/libQt5Gui.so.5 ln -s /usr/lib/x86_64-linux-gnu/libQt5Gui.so.5 /opt/sogoupinyin/files/lib/qt5/lib/libQt5Gui.so.5 rm /opt/sogoupinyin/files/lib/qt5/lib/libQt5Widgets.so.5 ln -s /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5 /opt/sogoupinyin/files/lib/qt5/lib/libQt5Widgets.so.5 rm /opt/sogoupinyin/files/lib/qt5/lib/libQt5DBus.so.5 ln -s /usr/lib/x86_64-linux-gnu/libQt5DBus.so.5 /opt/sogoupinyin/files/lib/qt5/lib/libQt5DBus.so.5 rm /opt/sogoupinyin/files/lib/qt5/lib/libQt5Qml.so.5 ln -s /usr/lib/x86_64-linux-gnu/libQt5Qml.so.5 /opt/sogoupinyin/files/lib/qt5/lib/libQt5Qml.so.5 rm /opt/sogoupinyin/files/lib/qt5/lib/libQt5Network.so.5 ln -s /usr/lib/x86_64-linux-gnu/libQt5Network.so.5 /opt/sogoupinyin/files/lib/qt5/lib/libQt5Network.so.5 rm /opt/sogoupinyin/files/lib/qt5/lib/libQt5Quick.so.5 ln -s /usr/lib/x86_64-linux-gnu/libQt5Quick.so.5 /opt/sogoupinyin/files/lib/qt5/lib/libQt5Quick.so.5 rm /opt/sogoupinyin/files/lib/qt5/lib/libQt5QuickWidgets.so.5 ln -s /usr/lib/x86_64-linux-gnu/libQt5QuickWidgets.so.5 /opt/sogoupinyin/files/lib/qt5/lib/libQt5QuickWidgets.so.5 rm /opt/sogoupinyin/files/lib/qt5/lib/libQt5Svg.so.5 ln -s /usr/lib/x86_64-linux-gnu/libQt5Svg.so.5 /opt/sogoupinyin/files/lib/qt5/lib/libQt5Svg.so.5 rm /opt/sogoupinyin/files/lib/qt5/lib/libQt5XcbQpa.so.5 ln -s /usr/lib/x86_64-linux-gnu/libQt5XcbQpa.so.5 /opt/sogoupinyin/files/lib/qt5/lib/libQt5XcbQpa.so.5 rm /opt/sogoupinyin/files/lib/qt5/lib/libFcitxQt5DBusAddons.so.1 ln -s /usr/lib/x86_64-linux-gnu/libFcitxQt5DBusAddons.so.1 /opt/sogoupinyin/files/lib/qt5/lib/libFcitxQt5DBusAddons.so.1 rm /opt/sogoupinyin/files/lib/qt5/lib/libgsettings-qt.so.1 ln -s /usr/lib/x86_64-linux-gnu/libgsettings-qt.so.1 /opt/sogoupinyin/files/lib/qt5/lib/libgsettings-qt.so.1 rm /opt/sogoupinyin/files/lib/qt5/lib/libpcre.so.3 ln -s /usr/lib/x86_64-linux-gnu/libpcre.so.3 /opt/sogoupinyin/files/lib/qt5/lib/libpcre.so.3 # plugins rm /opt/sogoupinyin/files/lib/qt5/plugins/iconengines/libqsvgicon.so ln -s /usr/lib/x86_64-linux-gnu/qt5/plugins/iconengines/libqsvgicon.so /opt/sogoupinyin/files/lib/qt5/plugins/iconengines/libqsvgicon.so rm /opt/sogoupinyin/files/lib/qt5/plugins/imageformats/libqsvg.so ln -s /usr/lib/x86_64-linux-gnu/qt5/plugins/imageformats/libqsvg.so /opt/sogoupinyin/files/lib/qt5/plugins/imageformats/libqsvg.so rm /opt/sogoupinyin/files/lib/qt5/plugins/platforminputcontexts/libfcitxplatforminputcontextplugin.so ln -s /usr/lib/x86_64-linux-gnu/qt5/plugins/platforminputcontexts/libfcitxplatforminputcontextplugin.so /opt/sogoupinyin/files/lib/qt5/plugins/platforminputcontexts/libfcitxplatforminputcontextplugin.so rm /opt/sogoupinyin/files/lib/qt5/plugins/platforms/libqlinuxfb.so ln -s /usr/lib/x86_64-linux-gnu/qt5/plugins/platforms/libqlinuxfb.so /opt/sogoupinyin/files/lib/qt5/plugins/platforms/libqlinuxfb.so rm /opt/sogoupinyin/files/lib/qt5/plugins/platforms/libqminimal.so ln -s /usr/lib/x86_64-linux-gnu/qt5/plugins/platforms/libqminimal.so /opt/sogoupinyin/files/lib/qt5/plugins/platforms/libqminimal.so rm /opt/sogoupinyin/files/lib/qt5/plugins/platforms/libqoffscreen.so ln -s /usr/lib/x86_64-linux-gnu/qt5/plugins/platforms/libqoffscreen.so /opt/sogoupinyin/files/lib/qt5/plugins/platforms/libqoffscreen.so rm /opt/sogoupinyin/files/lib/qt5/plugins/platforms/libqxcb.so ln -s /usr/lib/x86_64-linux-gnu/qt5/plugins/platforms/libqxcb.so /opt/sogoupinyin/files/lib/qt5/plugins/platforms/libqxcb.so rm /opt/sogoupinyin/files/lib/qt5/plugins/xcbglintegrations/libqxcb-glx-integration.so ln -s /usr/lib/x86_64-linux-gnu/qt5/plugins/xcbglintegrations/libqxcb-glx-integration.so /opt/sogoupinyin/files/lib/qt5/plugins/xcbglintegrations/libqxcb-glx-integration.so
环境变量设置：CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC 为 1 解决
USE information_schema; SELECT T.TABLE_NAME as '表名', T.TABLE_COMMENT as '表说明', C.COLUMN_NAME AS '字段名', C.COLUMN_COMMENT AS '字段说明', C.COLUMN_TYPE AS '数据类型', C.IS_NULLABLE AS '允许为空', C.EXTRA AS '其他属性' FROM COLUMNS C INNER JOIN TABLES T ON C.TABLE_SCHEMA = T.TABLE_SCHEMA AND C.TABLE_NAME = T.TABLE_NAME WHERE T.TABLE_SCHEMA = '表名'
# import traceback # # for a in traceback.format_stack(): # print(a)
swoole进程模型 Reactor、manager、Worker、Task的关系
swoole的进程理解是一个有点点烧脑的地方,但是理解了还是简单,官方的文档其实说得比较具体,但是不够直观自己重新整理下=============================官方文档===============================三种角色分别的职责是：Reactor线程负责维护客户端机器的TCP连接、处理网络IO、收发数据 完全是异步非阻塞的模式 全部为C代码，除Start/Shudown事件回调外，不执行任何PHP代码 将TCP客户端发来的数据缓冲、拼接、拆分成完整的一个请求数据包 Reactor以多线程的方式运行 Worker进程接受由Reactor线程投递的请求数据包，并执行PHP回调函数处理数据 生成响应数据并发给Reactor线程，由Reactor线程发送给TCP客户端 可以是异步非阻塞模式，也可以是同步阻塞模式 Worker以多进程的方式运行 Task进程接受由Worker进程通过swoole_server->task/taskwait方法投递的任务 处理任务，并将结果数据返回给Worker进程 完全是同步阻塞模式 Task以多进程的方式运行 关系 可以理解为reactor就是nginx，worker就是php-fpm。reactor线程异步并行地处理网络请求，然后再转发给worker进程中去处理。reactor和worker间通过IPC方式通信。swoole的reactor，worker，task_worker之间可以紧密的结合起来，提供更高级的使用方式。一个更通俗的比喻，假设Server就是一个工厂，那reactor就是销售，帮你接项目订单。而worker就是工人，当销售接到订单后，worker去工作生产出客户要的东西。而task_worker可以理解为行政人员，可以帮助worker干些杂事，让worker专心工作。底层会为Worker进程、Task进程分配一个唯一的ID 不同的task/worker进程之间可以通过sendMessage接口进行通信=============================官方文档完===============================[...]