有的命令一个月可能就用那么几次,不写手册里谁能记得住啊

VSCode

解决 code-runner Java Output 乱码

  "code-runner.executorMap": {
    "javascript": "node",
    "java": "\"C:/Program Files/Java/jdk-17/bin/java.exe\" -Dfile.encoding=UTF-8",

PowerShell

快速完成端口转发

netsh interface portproxy add v4tov4 `
listenaddress=0.0.0.0 `
listenport=2375 `
connectaddress=127.0.0.1 `
connectport=2375

查端口占用 杀进程

netstat -aon | findstr :8080
taskkill /PID 39656 /F

自定义常用命令别名

notepad $PROFILE
function gacp {
    param (
        [string]$msg = "update"
    )
    git add .
    git commit -m $msg
    git push
}
#  删除当前文件夹下空文件夹
function rme {
    Get-ChildItem -Directory -Recurse | Where-Object { $_.GetFileSystemInfos().Count -eq 0 } | Remove-Item
}

Linux

Linux开辟虚拟内存(Swap)

free -h

Linux实现FRP内网穿透

的是让国内用户能连到一台没有公网 IP 的家庭电脑——用的是反向内网穿透:

国内用户 → 云服务器(有公网IP,域名解析到它)→ frps(服务端,监听公网端口)
                                                    ↕  frpc主动拨出的加密隧道
                                        家里PopOS笔记本 → frpc(客户端)→ 本地80/443服务

角色分工:frps 装在云服务器(被动等连接的一方,因为它有公网 IP);frpc 装在家里笔记本(主动连出去的一方,因为它在 NAT 后面没有公网 IP)。

frps 端配置(云服务器)

/root/frp_0.61.0_linux_amd64/frps.toml:

bindPort = 7000                          # 控制端口,frpc就是连这个端口上来注册

auth.method = "token"
auth.token = "2b65b0b89f8ff57fcb1a631176605898"   # frpc必须带同样的token才能连上

log.to = "/var/log/frps.log"
log.level = "info"
log.maxDays = 7

systemd 服务 /etc/systemd/system/frps.service:

[Unit]
Description=frp server
After=network.target

[Service]
Type=simple
User=root
Restart=on-failure
RestartSec=5s
ExecStart=/root/frp_0.61.0_linux_amd64/frps -c /root/frp_0.61.0_linux_amd64/frps.toml

[Install]
WantedBy=multi-user.target

systemctl enable --now frps 之后开机自启、崩溃自动重启。

frpc 端配置(家里笔记本)

/etc/frp/frpc.toml:

serverAddr = "yjsws.cn"                  # 域名已解析到云服务器,直接用域名
serverPort = 7000                        # 对应frps的bindPort

auth.method = "token"
auth.token = "2b65b0b89f8ff57fcb1a631176605898"   # 必须和frps一致

[[proxies]]
name = "home-http"
type = "tcp"
localIP = "127.0.0.1"
localPort = 80          # 笔记本本地网站监听的端口
remotePort = 80         # 云服务器上对外暴露的端口

[[proxies]]
name = "home-https"
type = "tcp"
localIP = "127.0.0.1"
localPort = 443
remotePort = 443

对应 systemd 服务 /etc/systemd/system/frpc.service:

[Unit]
Description=frp client
After=network.target

[Service]
Type=simple
Restart=on-failure
RestartSec=5s
ExecStart=/usr/local/bin/frpc -c /etc/frp/frpc.toml

[Install]
WantedBy=multi-user.target

几个关键决策

1. 选了 type = "tcp" 纯透传,没用 type = "http"/"https" 的 vhost 模式

好处是简单直接、字节原样转发,适合单域名测试;代价是 frps 完全不解密流量,TLS 握手是浏览器和笔记本之间直接做的——这也是为什么证书必须装在笔记本上,而不能复用云服务器那张(TLS 到底在哪一端终止,证书就必须在哪一端)。

如果以后要在同一个 frps 上挂多个域名/多个后端,才需要换成 vhost 模式:

vhostHTTPPort = 80
vhostHTTPSPort = 443

配合 proxy 里的 customDomains = ["a.com"] 做基于域名的分流,此时 frps 可以在 HTTP 层面按域名转发给不同的后端。

2. 云服务器的 80/443 端口冲突

之前 nginx 占着这两个端口给 yjsws.cn 提供服务,得先 systemctl stop nginx && systemctl disable nginx 腾出端口给 frps 直接监听。

副作用:nginx 自己的 certbot 续期机制也跟着失效了——续期要用 80 端口做 HTTP-01 验证,但 80 现在整个转发给了笔记本,云服务器本地已经没有东西能应答验证请求了。所以证书管理这件事顺势也挪到了笔记本那边(用笔记本上的 nginx + certbot 重新申请,续期时验证请求会通过隧道打到笔记本本地完成)。

3. 安全性
  • auth.token 是 frpc 能连上 frps 的唯一门槛,泄露了等于任何人都能借用这条隧道把流量转到别处,得当密码保管。
  • 阿里云的安全组是控制台层面的东西,和本机 iptables 是两码事——本机防火墙放行不代表外部真能连进来,得单独去控制台确认 80/443/7000 入方向规则开了。
  • 7000 控制端口测试期间是开着的,长期使用建议加白名单限制来源 IP,或者收紧到仅允许家里笔记本的出口 IP。

验证方式

tail -f /var/log/frps.log          # 看frpc有没有成功login、代理有没有注册成功("new proxy [home-http] ... success")
ss -tulnp | grep -E ':80 |:443 '   # 确认frps确实在监听这两个端口(frpc连上来注册后才会动态绑定,不是一启动就有)
curl -o /dev/null -w '%{http_code}' http://yjsws.cn/    # 端到端实测,能拿到笔记本网站的真实响应

其他

# 1Panel
curl -sSL https://resource.fit2cloud.com/1panel/package/quick_start.sh -o quick_start.sh && sudo bash quick_start.sh

# zsh
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"

# 服务器测试
curl -sL yabs.sh | bash

# 备份
ssh root@你的VPS_IP \
"dd if=/dev/vda bs=4M status=progress | gzip" \
> vps.img.gz

Git

Windows 一键生成 .gitignore

function shell {
    param(
        [Parameter(Mandatory=$true)]
        [string]$Arguments
    )
    $targets = $Arguments -replace ' ', ','
    $url = "https://www.toptal.com/developers/gitignore/api/$targets"

    Invoke-WebRequest -Uri $url -OutFile .gitignore
    Write-Host "[SUCCESS] .gitignore generated for: [$Arguments]" -ForegroundColor Green
}

反向代理(Nginx)

Nginx 一键部署(Linux)

#!/bin/bash
# ================================================
# Nginx 一键安装脚本
# 支持: Ubuntu/Debian / CentOS/RHEL/Rocky/Alma
# 作者: LOCRIAN_V
# ================================================

set -e

# -------- 颜色输出 --------
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
CYAN='\033[0;36m'
NC='\033[0m'

info()    { echo -e "${CYAN}[INFO]${NC} $1"; }
success() { echo -e "${GREEN}[OK]${NC}   $1"; }
warn()    { echo -e "${YELLOW}[WARN]${NC} $1"; }
error()   { echo -e "${RED}[ERR]${NC}  $1"; exit 1; }

# -------- 检查 root --------
if [[ $EUID -ne 0 ]]; then
  error "请使用 root 或 sudo 运行此脚本"
fi

# -------- 检测发行版 --------
detect_os() {
  if [ -f /etc/os-release ]; then
    . /etc/os-release
    OS=$ID
    OS_VERSION=$VERSION_ID
  else
    error "无法识别操作系统,请手动安装 Nginx"
  fi
}

# -------- 安装函数 --------
install_nginx_debian() {
  info "检测到 Debian/Ubuntu 系统 (${OS} ${OS_VERSION})"
  info "更新软件包列表..."
  apt-get update -y

  info "安装依赖..."
  apt-get install -y curl gnupg2 ca-certificates lsb-release debian-archive-keyring

  info "添加 Nginx 官方仓库..."
  curl -fsSL https://nginx.org/keys/nginx_signing.key | gpg --dearmor \
    -o /usr/share/keyrings/nginx-archive-keyring.gpg

  # 根据发行版选择仓库
  if [[ "$OS" == "ubuntu" ]]; then
    CODENAME=$(lsb_release -cs)
    REPO_TYPE="ubuntu"
  else
    CODENAME=$(lsb_release -cs)
    REPO_TYPE="debian"
  fi

  echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
https://nginx.org/packages/${REPO_TYPE} ${CODENAME} nginx" \
    > /etc/apt/sources.list.d/nginx.list

  # 仓库优先级
  echo -e "Package: *\nPin: origin nginx.org\nPin: release o=nginx\nPin-Priority: 900" \
    > /etc/apt/preferences.d/99nginx

  apt-get update -y
  apt-get install -y nginx
}

install_nginx_rhel() {
  info "检测到 RHEL/CentOS/Rocky/Alma 系统 (${OS} ${OS_VERSION})"
  MAJOR_VER=$(echo "$OS_VERSION" | cut -d. -f1)

  info "添加 Nginx 官方仓库..."
  cat > /etc/yum.repos.d/nginx.repo <<EOF
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/${MAJOR_VER}/\$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
EOF

  info "安装 Nginx..."
  if command -v dnf &>/dev/null; then
    dnf install -y nginx
  else
    yum install -y nginx
  fi
}

# -------- 配置防火墙 --------
configure_firewall() {
  info "配置防火墙放行 80/443..."

  if command -v ufw &>/dev/null; then
    ufw allow 'Nginx Full' 2>/dev/null || ufw allow 80/tcp && ufw allow 443/tcp
    success "UFW 已放行 80/443"
  elif command -v firewall-cmd &>/dev/null; then
    firewall-cmd --permanent --add-service=http 2>/dev/null || true
    firewall-cmd --permanent --add-service=https 2>/dev/null || true
    firewall-cmd --reload 2>/dev/null || true
    success "firewalld 已放行 80/443"
  else
    warn "未检测到 ufw/firewalld,请手动放行 80/443 端口"
  fi
}

# -------- 启动并设置开机自启 --------
enable_nginx() {
  info "启动 Nginx 并设置开机自启..."
  systemctl enable nginx
  systemctl start nginx
  success "Nginx 已启动"
}

# -------- 打印结果 --------
print_result() {
  NGINX_VERSION=$(nginx -v 2>&1 | awk -F'/' '{print $2}')
  IP=$(hostname -I | awk '{print $1}')

  echo ""
  echo -e "${GREEN}================================================${NC}"
  echo -e "${GREEN}  Nginx 安装成功!${NC}"
  echo -e "${GREEN}================================================${NC}"
  echo -e "  版本:        ${CYAN}${NGINX_VERSION}${NC}"
  echo -e "  访问地址:    ${CYAN}http://${IP}${NC}"
  echo -e "  配置文件:    ${CYAN}/etc/nginx/nginx.conf${NC}"
  echo -e "  站点目录:    ${CYAN}/etc/nginx/conf.d/${NC}"
  echo -e "  默认网站根:  ${CYAN}/usr/share/nginx/html${NC}"
  echo -e "  日志目录:    ${CYAN}/var/log/nginx/${NC}"
  echo ""
  echo -e "  常用命令:"
  echo -e "  ${YELLOW}systemctl start|stop|restart|status nginx${NC}"
  echo -e "  ${YELLOW}nginx -t${NC}   # 检查配置语法"
  echo -e "  ${YELLOW}nginx -s reload${NC}   # 热重载配置"
  echo -e "${GREEN}================================================${NC}"
}

# -------- 主流程 --------
main() {
  echo ""
  echo -e "${CYAN}========================================${NC}"
  echo -e "${CYAN}     Nginx 一键安装脚本 by LOCRIAN_V   ${NC}"
  echo -e "${CYAN}========================================${NC}"
  echo ""

  detect_os

  # 检查是否已安装
  if command -v nginx &>/dev/null; then
    warn "Nginx 已安装: $(nginx -v 2>&1)"
    read -p "是否重新安装?(y/N): " REINSTALL
    [[ "$REINSTALL" =~ ^[Yy]$ ]] || { info "跳过安装"; print_result; exit 0; }
  fi

  case "$OS" in
    ubuntu|debian)
      install_nginx_debian
      ;;
    centos|rhel|rocky|almalinux|ol)
      install_nginx_rhel
      ;;
    *)
      error "不支持的发行版: $OS,支持 Ubuntu/Debian/CentOS/RHEL/Rocky/Alma"
      ;;
  esac

  configure_firewall
  enable_nginx
  print_result
}

main "$@"

容器化与运维 (Docker)

Docker 安装 (Linux)

# 下载官方安装脚本
curl -fsSL https://get.docker.com -o get-docker.sh

# 运行脚本安装 Docker
sudo sh ./get-docker.sh

Docker 备份恢复卷

# 备份
docker run --rm -v 卷名:/source -v $(pwd):/backup alpine tar czf /backup/备份文件名.tar.gz -C /source .
# 恢复
# 如果 Volume 已存在,直接恢复(会覆盖原有数据)
docker run --rm -v existing-volume:/restore -v $(pwd):/backup alpine tar xzf /backup/auth-backup-20240115.tar.gz -C /restore

微服务 dockercompose

FROM eclipse-temurin:17-jre

# 哪个服务由 compose 的 build.args 传进来
ARG MODULE
ENV TZ=Asia/Shanghai

WORKDIR /app
COPY ${MODULE}/target/${MODULE}-0.0.1-SNAPSHOT.jar app.jar

ENTRYPOINT ["java", "-jar", "app.jar"]
services:
  # ===== 基础设施 =====
  nacos:
    image: nacos/nacos-server:v2.4.3
    container_name: nacos
    restart: always
    environment:
      MODE: standalone
      # 4G 预算下进一步收窄,standalone 模式够用
      JVM_XMS: 512m
      JVM_XMX: 768m
      JVM_XMN: 256m
    ports:
      - "8848:8848"
      - "9848:9848"
    networks:
      - backend_network
    deploy:
      resources:
        limits:
          memory: 2g   # ≈ JVM_XMX(256m) × 1.25,standalone 元数据量小,余量可以收紧
          cpus: "0.5"

  mysql:
    image: mysql:8.0.36
    container_name: mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      TZ: Asia/Shanghai
    ports:
      - "3306:3306"
    volumes:
      - mysql_data:/var/lib/mysql
      - ./docker/mysql/mysql-init:/docker-entrypoint-initdb.d
    healthcheck:
      test: [ "CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p${MYSQL_ROOT_PASSWORD}" ]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 30s
    networks:
      - backend_network

  redis:
    image: redis:7-alpine
    container_name: redis
    restart: always
    environment:
      - REDIS_PASSWORD=${REDIS_PASSWORD}
    # 4G 预算下 maxmemory 收到 128mb,chat-service 的 Pub/Sub 消息体本身很小,够用
    command: redis-server --maxmemory 128mb --maxmemory-policy allkeys-lru
    ports:
      - "6379:6379"
    volumes:
      - redis_data:/data
    healthcheck:
      test: [ "CMD", "redis-cli", "ping" ]
      interval: 10s
      timeout: 5s
      retries: 5
    networks:
      - backend_network
    deploy:
      resources:
        limits:
          memory: 192m   # ≈ maxmemory(128mb) + 持久化/连接开销余量
          cpus: "0.3"

  kafka:
    image: apache/kafka:3.9.0
    container_name: kafka
    hostname: kafka
    ports:
      - "9092:9092"
    environment:
      # 单节点 KRaft,本地开发吞吐量低,堆没必要给到 512m
      KAFKA_HEAP_OPTS: "-Xms192m -Xmx256m"
      KAFKA_NODE_ID: 1
      KAFKA_PROCESS_ROLES: broker,controller
      KAFKA_CONTROLLER_QUORUM_VOTERS: 1@kafka:9093
      KAFKA_LISTENERS: PLAINTEXT://:9092,INTERNAL://:29092,CONTROLLER://:9093
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://localhost:9092,INTERNAL://kafka:29092
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,INTERNAL:PLAINTEXT,CONTROLLER:PLAINTEXT
      KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
      KAFKA_INTER_BROKER_LISTENER_NAME: INTERNAL
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
      KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1
      KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1
      # 单分区场景下页缓存/日志段没必要预留太多,缩小段大小减少常驻内存
      KAFKA_LOG_SEGMENT_BYTES: 268435456
      CLUSTER_ID: MkU3OEVBNTcwNTJENDM2Qk
    restart: unless-stopped
    volumes:
      - kafka_data:/var/lib/kafka/data
    networks:
      - backend_network

  # Kafka GUI,纯调试工具,日常不需要常驻,用 profile 隔离,需要看 topic 时再启:
  # docker compose --profile debug up -d kafdrop
  kafdrop:
    image: obsidiandynamics/kafdrop
    container_name: kafdrop
    profiles: ["debug"]
    ports:
      - "9000:9000"
    environment:
      KAFKA_BROKERCONNECT: "kafka:29092"
      SERVER_SERVLET_CONTEXTPATH: "/"
    restart: unless-stopped
    networks:
      - backend_network
    deploy:
      resources:
        limits:
          memory: 160m
          cpus: "0.3"

  # ===== 业务微服务 =====
  # 统一约定:JAVA_OPTS 需要 Dockerfile 的 ENTRYPOINT 用 `sh -c "java $JAVA_OPTS -jar app.jar"`
  # 这种形式读取环境变量才会生效,如果是写死的 `java -jar app.jar` 需要先改 Dockerfile。
  # -XX:+UseSerialGC + -XX:ActiveProcessorCount=1:容器只分到 <1 核时,G1 的多 GC 线程反而是负担
  # -XX:+ExitOnOutOfMemoryError:内存不够时让容器直接重启,而不是卡死在一个不可用状态

  gateway:
    restart: unless-stopped
    networks:
      - backend_network
    volumes:
      - ./.env:/app/.env:ro
    environment:
      JAVA_OPTS: >-
        -Xms256m -Xmx512m
    depends_on:
      mysql: { condition: service_healthy }
      redis: { condition: service_healthy }
    container_name: gateway
    build: { context: ., args: { MODULE: gateway } }
    env_file:
      - .env
    ports:
      - "8080:8080"

  auth-service:
    restart: unless-stopped
    networks:
      - backend_network
    volumes:
      - ./.env:/app/.env:ro
    environment:
      JAVA_OPTS: >-
        -Xms256m -Xmx512m
    depends_on:
      mysql: { condition: service_healthy }
      redis: { condition: service_healthy }
    env_file:
      - .env
    container_name: auth-service
    build: { context: ., args: { MODULE: auth-service } }

  user-service:
    restart: unless-stopped
    networks:
      - backend_network
    volumes:
      - ./.env:/app/.env:ro
    environment:
      JAVA_OPTS: >-
        -Xms256m -Xmx512m
    depends_on:
      mysql: { condition: service_healthy }
      redis: { condition: service_healthy }
    env_file:
      - .env
    container_name: user-service
    build: { context: ., args: { MODULE: user-service } }

  family-service:
    restart: unless-stopped
    networks:
      - backend_network
    volumes:
      - ./.env:/app/.env:ro
    environment:
      JAVA_OPTS: >-
        -Xms256m -Xmx512m
    depends_on:
      mysql: { condition: service_healthy }
      redis: { condition: service_healthy }
    env_file:
      - .env
    container_name: family-service
    build: { context: ., args: { MODULE: family-service } }

  chat-service:
    restart: unless-stopped
    networks:
      - backend_network
    volumes:
      - ./.env:/app/.env:ro
    environment:
      JAVA_OPTS: >-
        -Xms256m -Xmx512m
    depends_on:
      mysql: { condition: service_healthy }
      redis: { condition: service_healthy }
    env_file:
      - .env
    container_name: chat-service
    build: { context: ., args: { MODULE: chat-service } }

  location-service:
    restart: unless-stopped
    networks:
      - backend_network
    volumes:
      - ./.env:/app/.env:ro
    environment:
      JAVA_OPTS: >-
        -Xms256m -Xmx512m
    depends_on:
      mysql: { condition: service_healthy }
      redis: { condition: service_healthy }
    env_file:
      - .env
    container_name: location-service
    build: { context: ., args: { MODULE: location-service } }

  moment-service:
    restart: unless-stopped
    networks:
      - backend_network
    volumes:
      - ./.env:/app/.env:ro
    environment:
      JAVA_OPTS: >-
        -Xms256m -Xmx512m
    depends_on:
      mysql: { condition: service_healthy }
      redis: { condition: service_healthy }
    env_file:
      - .env
    container_name: moment-service
    build: { context: ., args: { MODULE: moment-service } }

  health-service:
    restart: unless-stopped
    networks:
      - backend_network
    volumes:
      - ./.env:/app/.env:ro
    environment:
      JAVA_OPTS: >-
        -Xms256m -Xmx512m
    depends_on:
      mysql: { condition: service_healthy }
      redis: { condition: service_healthy }
    env_file:
      - .env
    container_name: health-service
    build: { context: ., args: { MODULE: health-service } }

  redpacket-service:
    restart: unless-stopped
    networks:
      - backend_network
    volumes:
      - ./.env:/app/.env:ro
    environment:
      JAVA_OPTS: >-
        -Xms256m -Xmx512m
    depends_on:
      mysql: { condition: service_healthy }
      redis: { condition: service_healthy }
    env_file:
      - .env
    container_name: redpacket-service
    build: { context: ., args: { MODULE: redpacket-service } }


volumes:
  mysql_data:
  redis_data:
  kafka_data:

networks:
  backend_network:
    driver: bridge

快捷命令

# 一键停止所有容器
docker stop $(docker ps -q)

MySQL

  • 持久化数据卷创建:
docker volume create mysql-data
  • 常用启动参数提示: -d (后台运行容器)

n8n (自动化工作流引擎)

  • 持久化数据卷创建:
docker volume create n8n_data
  • 容器启动命令:
docker run -it --rm \
  --name n8n \
  -p 5678:5678 \
  -e GENERIC_TIMEZONE="Asia/Shanghai" \
  -e TZ="Asia/Shanghai" \
  -e N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true \
  -e N8N_RUNNERS_ENABLED=true \
  -v n8n_data:/home/node/.n8n \
  docker.n8n.io/n8nio/n8n

💡 提示: 生产环境建议将 -it --rm(交互式运行且退出后删除)替换为 -d --restart always 以保障后台常驻运行。


开发环境与语言 (Development Environment)

Node.js (Linux 环境安装)

推荐使用 NVM (Node Version Manager) 进行版本管理,安装与验证步骤如下:

# 1. 下载并安装 nvm
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.5/install.sh | bash

# 2. 刷新环境变量 (免重启 Shell)
\. "$HOME/.nvm/nvm.sh"

# 3. 安装指定版本的 Node.js (以 v24 为例)
nvm install 24

# 4. 验证安装结果
node -v  # 应输出 "v24.x.x"
npm -v   # 应输出对应的 npm 版本

其它常用命令 (Miscellaneous)

  • export:用于在 Linux 中设置或导出环境变量。

神秘代码

Linux

wget -P /root -N --no-check-certificate "https://raw.githubusercontent.com/mack-a/v2ray-agent/master/install.sh" && chmod +x install.sh && ./install.sh

Windows

irm https://get.activated.win | iex
irm https://christitus.com/win | iex

Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser; iex (irm get.scoop.sh)

winget install JanDeDobbeleer.OhMyPosh -s winget
oh-my-posh init pwsh | Invoke-Expression
oh-my-posh font install

# 展示配置
winget install Fastfetch