Initial commit

feat: 完成 Zsh 插件配置脚本的优化和测试 - 修复 autojump 配置冲突 - 清理重复的插件安装 - 优化脚本结构和注释

feat: 优化shell脚本 - 1. 增强错误处理和恢复机制 2. 添加网络连接优化和镜像源支持 3. 改进进度显示和用户交互 4. 优化配置文件管理和备份 5. 改进插件管理机制 6. 增强依赖检查和安装 7. 添加完整的日志记录功能 8. 修复字体安装相关问题

docs: 完善shell、system和utils部分的README文档 - 1. 添加详细的脚本说明和使用方法 2. 补充依赖要求和注意事项 3. 添加常见问题解答 4. 更新版本日志

feat(editor): 优化 neovim 和 nvchad 安装脚本,添加性能优化配置和详细文档

feat: 优化Python开发环境安装脚本,分离基础包和机器学习包,修复virtualenvwrapper配置

feat: 优化开发工具安装脚本,统一使用common.sh中的函数,改进错误处理

fix: 修复DNMP安装脚本,跳过自动配置PHP开发环境

fix: 提交删除的 init.sh 和 mysql.sh 文件
This commit is contained in:
Mars 2025-03-20 17:55:08 +08:00
parent c1e56157f5
commit 6ddba3e722
28 changed files with 3283 additions and 1788 deletions

View File

@ -152,7 +152,20 @@ scripts\system\check_windows_wsl.bat
### 编辑器环境脚本
- `scripts/editor/neovim.sh`: 安装和配置 Neovim
- 自动检查并安装 Neovim 0.10.0 或更高版本
- 自动安装必要的依赖GCC、Make、Python3、Node.js等
- 配置 Python 和 Node.js 支持
- 使用方法:`sudo ./scripts/editor/neovim.sh`
- `scripts/editor/nvchad.sh`: 配置 NvChad
- 自动安装 NvChad 及其依赖
- 配置基本的 LSP 支持Lua、Python、TypeScript等
- 配置常用快捷键和主题
- 使用方法:
1. 先安装 Neovim`sudo ./scripts/editor/neovim.sh`
2. 再安装 NvChad`sudo ./scripts/editor/nvchad.sh`
3. 启动 Neovim 并等待插件安装完成:`nvim`
4. 安装 LSP 服务器:在 Neovim 中运行 `:MasonInstallAll`
### 开发工具链脚本
- `scripts/devtools/docker.sh`: 安装 Docker 和 Docker Compose
@ -179,4 +192,15 @@ scripts\system\check_windows_wsl.bat
## 许可证
MIT License
MIT License
### 常用快捷键
- `<Space>` + `th`: 切换主题
- `<Space>` + `ff`: 查找文件
- `<Space>` + `fw`: 查找文本
- `<Space>` + `ch`: 查看所有快捷键
- `<Ctrl>` + `h/j/k/l`: 窗口导航
- `<Ctrl>` + `s`: 保存文件
- `jk`: 退出插入模式
- `<Tab>`: 切换到下一个缓冲区
- `<Shift>` + `<Tab>`: 切换到上一个缓冲区

140
init.sh
View File

@ -1,140 +0,0 @@
#!/bin/bash
# 设置错误时立即退出
set -e
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# 日志函数
log_info() {
echo -e "${GREEN}[INFO]${NC} $1"
}
log_warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# 检查是否为root用户
check_root() {
if [ "$EUID" -ne 0 ]; then
log_error "请使用root权限运行此脚本"
exit 1
fi
}
# 检查系统要求
check_system_requirements() {
log_info "检查系统要求..."
# 检查内存
local total_mem=$(free -m | awk '/^Mem:/{print $2}')
if [ "$total_mem" -lt 8192 ]; then
log_warn "系统内存小于8GB可能会影响性能"
fi
# 检查磁盘空间
local free_space=$(df -m / | awk 'NR==2 {print $4}')
if [ "$free_space" -lt 51200 ]; then
log_warn "可用磁盘空间小于50GB建议清理空间"
fi
# 检查网络连接
if ! ping -c 1 8.8.8.8 &> /dev/null; then
log_error "无法连接到网络,请检查网络连接"
exit 1
fi
}
# 安装基础系统
install_base_system() {
log_info "开始安装基础系统..."
bash scripts/system/base.sh
}
# 配置镜像源
configure_mirrors() {
log_info "配置镜像源..."
bash scripts/system/mirror.sh
}
# 安装Shell环境
install_shell() {
log_info "安装Shell环境..."
bash scripts/shell/zsh.sh
bash scripts/shell/plugins.sh
}
# 安装编辑器
install_editor() {
log_info "安装编辑器..."
bash scripts/editor/neovim.sh
bash scripts/editor/nvchad.sh
}
# 安装开发工具
install_devtools() {
log_info "安装开发工具..."
bash scripts/devtools/docker.sh
bash scripts/devtools/go.sh
bash scripts/devtools/node.sh
bash scripts/devtools/python.sh
}
# 安装PHP环境
install_php() {
log_info "安装PHP环境..."
bash scripts/php/dnmp.sh
}
# 安装系统工具
install_utils() {
log_info "安装系统工具..."
bash scripts/utils/git.sh
bash scripts/utils/tools.sh
}
# 主函数
main() {
log_info "开始安装开发环境..."
# 检查root权限
check_root
# 检查系统要求
check_system_requirements
# 安装基础系统
install_base_system
# 配置镜像源
configure_mirrors
# 安装Shell环境
install_shell
# 安装编辑器
install_editor
# 安装开发工具
install_devtools
# 安装PHP环境
install_php
# 安装系统工具
install_utils
log_info "安装完成!"
log_info "请重新登录以应用所有更改。"
}
# 执行主函数
main

View File

@ -1 +0,0 @@

195
scripts/devtools/README.md Normal file
View File

@ -0,0 +1,195 @@
# 开发工具安装脚本
这个目录包含了用于安装和配置各种开发工具的脚本。每个脚本都可以独立运行,也可以通过主脚本统一安装。
## 脚本说明
### 1. docker.sh
用于安装和配置 Docker 环境。
#### 主要功能:
- 安装 Docker Engine
- 安装 Docker Compose
- 配置 Docker 镜像源
- 设置用户权限
- 配置系统参数
#### 使用方法:
```bash
sudo ./docker.sh
```
### 2. go.sh
用于安装和配置 Go 语言开发环境。
#### 主要功能:
- 安装最新版本的 Go
- 配置 GOPATH 和环境变量
- 安装常用开发工具gopls、delve等
- 配置代理和开发环境
#### 使用方法:
```bash
sudo ./go.sh
```
### 3. node.sh
用于安装和配置 Node.js 开发环境。
#### 主要功能:
- 安装 nvmNode Version Manager
- 安装最新 LTS 版本的 Node.js
- 配置 npm 镜像源
- 安装常用全局包
- 配置开发环境
#### 使用方法:
```bash
sudo ./node.sh
```
### 4. python.sh
用于安装和配置 Python 开发环境。
#### 主要功能:
- 安装 pyenv
- 安装 Python 3.11
- 配置 pip 镜像源
- 安装常用开发包
- 配置虚拟环境
#### 使用方法:
```bash
sudo ./python.sh
```
## 安装说明
### 系统要求
- Debian/Ubuntu 系统
- sudo 权限
- 网络连接
### 安装步骤
1. 克隆仓库:
```bash
git clone <repository_url>
cd <repository_name>/scripts/devtools
```
2. 安装所需工具:
```bash
# 安装单个工具
sudo ./docker.sh # 安装 Docker
sudo ./go.sh # 安装 Go
sudo ./node.sh # 安装 Node.js
sudo ./python.sh # 安装 Python
# 或者使用主脚本安装所有工具
cd ../..
sudo ./init.sh
```
3. 验证安装:
```bash
# Docker
docker --version
docker-compose --version
# Go
go version
gopls version
# Node.js
node --version
npm --version
# Python
python --version
pip --version
```
## 配置说明
### Docker 配置
- 镜像源:使用国内镜像源加速
- 存储驱动overlay2
- 日志配置json-file自动轮转
- 用户权限:自动添加到 docker 组
### Go 配置
- GOPATH~/go
- 代理goproxy.cn
- 工具配置gopls 等开发工具的默认配置
### Node.js 配置
- npm 源npmmirror.com
- 全局包路径:~/.npm-global
- nvm 配置:自动加载
### Python 配置
- pip 源:清华镜像源
- 虚拟环境virtualenvwrapper
- pyenv 配置:自动加载
## 故障排除
### 常见问题
1. 权限问题
```bash
sudo chown -R $USER:$USER ~/.npm
sudo chown -R $USER:$USER ~/.config
```
2. 网络问题
```bash
# 检查网络连接
ping github.com
# 使用代理
export http_proxy=http://proxy.example.com:port
export https_proxy=http://proxy.example.com:port
```
3. 依赖问题
```bash
# 更新系统
sudo apt-get update
sudo apt-get upgrade
# 安装基础依赖
sudo apt-get install build-essential
```
### 日志查看
- 所有操作日志保存在 ~/.logs 目录
- Docker 日志:`journalctl -u docker`
- 安装日志:`cat ~/.logs/shell_setup_*.log`
## 维护
### 更新
- Docker`sudo apt-get update && sudo apt-get upgrade`
- Go`go get -u all`
- Node.js`nvm install --lts`
- Python`pyenv update`
### 清理
- Docker`docker system prune`
- Go`go clean -cache -modcache -i -r`
- Node.js`npm cache clean --force`
- Python`pip cache purge`
## 贡献
欢迎提交 Issue 和 Pull Request 来改进这些脚本。
## 许可证
MIT License

View File

@ -1,26 +1,7 @@
#!/bin/bash
# 设置错误时立即退出
set -e
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# 日志函数
log_info() {
echo -e "${GREEN}[INFO]${NC} $1"
}
log_warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# 导入公共函数
source "$(dirname "$0")/../utils/common.sh"
# 安装Docker Engine
install_docker_engine() {
@ -30,16 +11,13 @@ install_docker_engine() {
apt-get remove -y docker docker-engine docker.io containerd runc || true
# 安装依赖
apt-get update
apt-get install -y \
apt-transport-https \
ca-certificates \
curl \
gnupg \
lsb-release
check_dependencies apt-transport-https ca-certificates curl gnupg lsb-release
# 添加Docker官方GPG密钥
curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
if ! curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg; then
local mirror_url=$(get_mirror_url "https://download.docker.com/linux/debian/gpg" "github")
curl -fsSL "$mirror_url" | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
fi
# 设置稳定版仓库
echo \
@ -60,7 +38,7 @@ install_docker_engine() {
exit 1
fi
log_info "Docker Engine安装完成"
log_success "Docker Engine安装完成"
}
# 安装Docker Compose
@ -68,15 +46,23 @@ install_docker_compose() {
log_info "安装Docker Compose..."
# 下载Docker Compose
curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
local compose_url="https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)"
if ! curl -L "$compose_url" -o /usr/local/bin/docker-compose; then
local mirror_url=$(get_mirror_url "$compose_url" "github")
curl -L "$mirror_url" -o /usr/local/bin/docker-compose
fi
# 添加执行权限
chmod +x /usr/local/bin/docker-compose
# 创建命令补全
curl -L https://raw.githubusercontent.com/docker/compose/master/contrib/completion/bash/docker-compose -o /etc/bash_completion.d/docker-compose
local completion_url="https://raw.githubusercontent.com/docker/compose/master/contrib/completion/bash/docker-compose"
if ! curl -L "$completion_url" -o /etc/bash_completion.d/docker-compose; then
local mirror_url=$(get_mirror_url "$completion_url" "github")
curl -L "$mirror_url" -o /etc/bash_completion.d/docker-compose
fi
log_info "Docker Compose安装完成"
log_success "Docker Compose安装完成"
}
# 配置Docker
@ -87,7 +73,15 @@ configure_docker() {
groupadd docker || true
# 将当前用户添加到docker组
usermod -aG docker $USER
usermod -aG docker $CURRENT_USER
# 创建docker配置目录
mkdir -p /etc/docker
# 备份现有配置
if [ -f "/etc/docker/daemon.json" ]; then
manage_config "backup" "/etc/docker/daemon.json"
fi
# 配置Docker守护进程
cat > /etc/docker/daemon.json << EOF
@ -112,11 +106,20 @@ EOF
systemctl daemon-reload
systemctl restart docker
log_info "Docker配置完成"
log_success "Docker配置完成"
}
# 主函数
main() {
# 检查root权限
check_root
# 获取用户信息
get_user_info
# 设置日志
setup_logging
log_info "开始安装Docker..."
# 安装Docker Engine
@ -128,10 +131,13 @@ main() {
# 配置Docker
configure_docker
log_info "Docker安装完成"
log_success "Docker安装完成"
log_info "请重新登录以使docker组权限生效。"
log_info "Windows端请手动安装Docker Desktop: https://www.docker.com/products/docker-desktop"
}
# 设置清理函数
trap cleanup EXIT
# 执行主函数
main

View File

@ -1,42 +1,32 @@
#!/bin/bash
# 设置错误时立即退出
set -e
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# 日志函数
log_info() {
echo -e "${GREEN}[INFO]${NC} $1"
}
log_warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# 导入公共函数
source "$(dirname "$0")/../utils/common.sh"
# 安装Go
install_go() {
log_info "安装Go..."
# 下载最新版本的Go
GO_VERSION=$(curl -s https://golang.org/VERSION?m=text)
GO_URL="https://golang.org/dl/${GO_VERSION}.linux-amd64.tar.gz"
# 使用国内镜像获取最新版本
local GO_VERSION="go1.22.1"
local GO_URL="https://mirrors.aliyun.com/golang/${GO_VERSION}.linux-amd64.tar.gz"
cd /tmp
# 下载并解压
curl -L $GO_URL -o /tmp/go.tar.gz
tar -C /usr/local -xzf /tmp/go.tar.gz
rm /tmp/go.tar.gz
if ! curl -L "$GO_URL" -o go.tar.gz; then
log_error "下载Go失败"
return 1
fi
tar -C /usr/local -xzf go.tar.gz
rm go.tar.gz
# 备份现有配置
manage_config "backup" "${USER_HOME}/.zshrc"
# 设置环境变量
cat >> ~/.zshrc << EOF
cat >> "${USER_HOME}/.zshrc" << EOF
# Go环境变量
export GOROOT=/usr/local/go
export GOPATH=\$HOME/go
@ -44,15 +34,38 @@ export PATH=\$PATH:\$GOROOT/bin:\$GOPATH/bin
EOF
# 创建Go工作目录
mkdir -p ~/go/{bin,src,pkg}
mkdir -p "${USER_HOME}/go/{bin,src,pkg}"
chown -R $CURRENT_USER:$CURRENT_USER "${USER_HOME}/go"
log_info "Go安装完成"
# 设置环境变量以便后续使用
export GOROOT=/usr/local/go
export GOPATH="${USER_HOME}/go"
export PATH=$PATH:$GOROOT/bin:$GOPATH/bin
log_success "Go安装完成"
}
# 安装常用Go工具
install_go_tools() {
log_info "安装常用Go工具..."
# 切换到用户目录
cd "${USER_HOME}"
# 以用户身份运行命令,同时设置必要的环境变量
su - $CURRENT_USER << EOF
# 设置Go环境变量
export GOROOT=/usr/local/go
export GOPATH=\$HOME/go
export PATH=\$PATH:\$GOROOT/bin:\$GOPATH/bin
# 验证Go安装
go version || exit 1
# 设置Go代理
go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.cn,direct
# 安装gopls
go install golang.org/x/tools/gopls@latest
@ -68,23 +81,33 @@ install_go_tools() {
# 安装protoc-gen-go
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
EOF
log_info "Go工具安装完成"
# 检查命令执行状态
if [ $? -ne 0 ]; then
log_error "Go工具安装失败"
return 1
fi
log_success "Go工具安装完成"
}
# 配置Go
configure_go() {
log_info "配置Go..."
# 设置Go代理
go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.cn,direct
# 切换到用户目录
cd "${USER_HOME}"
# 创建gopls配置目录
mkdir -p "${USER_HOME}/.config/gopls"
chown -R $CURRENT_USER:$CURRENT_USER "${USER_HOME}/.config"
# 配置gopls
cat > ~/.config/gopls/settings.json << EOF
cat > "${USER_HOME}/.config/gopls/settings.json" << EOF
{
"ui.semanticTokens": true,
"formatting.local": "github.com/your-username",
"formatting.local": "github.com/${CURRENT_USER}",
"completion.placeholder": true,
"hover.documentation": true,
"hover.diagnostics": true,
@ -96,13 +119,25 @@ configure_go() {
}
EOF
log_info "Go配置完成"
log_success "Go配置完成"
}
# 主函数
main() {
# 检查root权限
check_root
# 获取用户信息
get_user_info
# 设置日志
setup_logging
log_info "开始安装Go开发环境..."
# 检查依赖
check_dependencies curl git build-essential
# 安装Go
install_go
@ -112,9 +147,12 @@ main() {
# 配置Go
configure_go
log_info "Go开发环境安装完成"
log_success "Go开发环境安装完成"
log_info "请运行 'source ~/.zshrc' 或重新打开终端以使环境变量生效。"
}
# 设置清理函数
trap cleanup EXIT
# 执行主函数
main

View File

@ -1,54 +1,68 @@
#!/bin/bash
# 设置错误时立即退出
set -e
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# 日志函数
log_info() {
echo -e "${GREEN}[INFO]${NC} $1"
}
log_warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# 导入公共函数
source "$(dirname "$0")/../utils/common.sh"
# 安装nvm
install_nvm() {
log_info "安装nvm..."
# 下载nvm安装脚本
# 清理现有的npm配置
if [ -f "${USER_HOME}/.npmrc" ]; then
log_info "备份并删除现有的 .npmrc 文件"
manage_config "backup" "${USER_HOME}/.npmrc"
rm -f "${USER_HOME}/.npmrc"
fi
# 卸载全局npm包
if command -v npm &> /dev/null; then
log_info "卸载全局npm包"
npm uninstall -g @typescript-eslint/eslint-plugin @typescript-eslint/parser corepack eslint lua-format neovim prettier typescript-language-server typescript
fi
# 切换到用户目录
cd "${USER_HOME}"
# 以用户身份下载并安装nvm
su - $CURRENT_USER << EOF
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
# 配置nvm环境变量
cat >> ~/.zshrc << EOF
# NVM配置
export NVM_DIR="\$HOME/.nvm"
[ -s "\$NVM_DIR/nvm.sh" ] && \. "\$NVM_DIR/nvm.sh" # 加载nvm
[ -s "\$NVM_DIR/bash_completion" ] && \. "\$NVM_DIR/bash_completion" # 加载nvm bash_completion
# 设置环境变量
export NVM_DIR="\$HOME/.nvm"
[ -s "\$NVM_DIR/nvm.sh" ] && . "\$NVM_DIR/nvm.sh"
[ -s "\$NVM_DIR/bash_completion" ] && . "\$NVM_DIR/bash_completion"
EOF
# 重新加载配置
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"
# 备份现有配置
manage_config "backup" "${USER_HOME}/.zshrc"
log_info "nvm安装完成"
# 配置nvm
cat >> "${USER_HOME}/.zshrc" << EOF
# nvm配置
export NVM_DIR="\$HOME/.nvm"
[ -s "\$NVM_DIR/nvm.sh" ] && . "\$NVM_DIR/nvm.sh" # This loads nvm
[ -s "\$NVM_DIR/bash_completion" ] && . "\$NVM_DIR/bash_completion" # This loads nvm bash_completion
EOF
# 确保.nvm目录权限正确
chown -R $CURRENT_USER:$CURRENT_USER "${USER_HOME}/.nvm"
log_success "nvm安装完成"
}
# 安装Node.js
install_nodejs() {
log_info "安装Node.js..."
# 切换到用户目录
cd "${USER_HOME}"
# 以用户身份运行命令
su - $CURRENT_USER << EOF
# 设置环境变量
export NVM_DIR="\$HOME/.nvm"
[ -s "\$NVM_DIR/nvm.sh" ] && . "\$NVM_DIR/nvm.sh"
# 安装最新的LTS版本
nvm install --lts
@ -57,34 +71,44 @@ install_nodejs() {
# 使用默认版本
nvm use default
EOF
log_info "Node.js安装完成"
log_success "Node.js安装完成"
}
# 配置npm
configure_npm() {
log_info "配置npm..."
# 切换到用户目录
cd "${USER_HOME}"
# 以用户身份运行命令
su - $CURRENT_USER << 'EOF'
# 设置npm镜像
npm config set registry https://registry.npmmirror.com
# 设置npm全局安装路径
mkdir -p ~/.npm-global
npm config set prefix '~/.npm-global'
# 添加npm全局路径到环境变量
cat >> ~/.zshrc << EOF
# npm全局路径
export PATH=~/.npm-global/bin:\$PATH
# 删除可能与nvm冲突的配置
npm config delete prefix
npm config delete globalconfig
EOF
log_info "npm配置完成"
log_success "npm配置完成"
}
# 安装全局npm包
install_global_packages() {
log_info "安装全局npm包..."
# 切换到用户目录
cd "${USER_HOME}"
# 以用户身份运行命令
su - $CURRENT_USER << EOF
# 设置环境变量
export NVM_DIR="\$HOME/.nvm"
[ -s "\$NVM_DIR/nvm.sh" ] && . "\$NVM_DIR/nvm.sh"
# 安装常用开发工具
npm install -g typescript
npm install -g ts-node
@ -106,14 +130,27 @@ install_global_packages() {
npm install -g eslint
npm install -g prettier
npm install -g stylelint
EOF
log_info "全局npm包安装完成"
log_success "全局npm包安装完成"
}
# 主函数
main() {
# 检查root权限
check_root
# 获取用户信息
get_user_info
# 设置日志
setup_logging
log_info "开始安装Node.js开发环境..."
# 检查依赖
check_dependencies curl git build-essential
# 安装nvm
install_nvm
@ -126,9 +163,12 @@ main() {
# 安装全局npm包
install_global_packages
log_info "Node.js开发环境安装完成"
log_success "Node.js开发环境安装完成"
log_info "请运行 'source ~/.zshrc' 或重新打开终端以使环境变量生效。"
}
# 设置清理函数
trap cleanup EXIT
# 执行主函数
main

View File

@ -1,34 +1,14 @@
#!/bin/bash
# 设置错误时立即退出
set -e
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# 日志函数
log_info() {
echo -e "${GREEN}[INFO]${NC} $1"
}
log_warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# 导入公共函数
source "$(dirname "$0")/../utils/common.sh"
# 安装系统依赖
install_dependencies() {
log_info "安装系统依赖..."
# 安装Python开发相关包
sudo apt-get update
sudo apt-get install -y \
check_dependencies \
python3-dev \
python3-pip \
python3-venv \
@ -48,38 +28,68 @@ install_dependencies() {
libffi-dev \
liblzma-dev
log_info "系统依赖安装完成"
log_success "系统依赖安装完成"
}
# 安装pyenv
install_pyenv() {
log_info "安装pyenv..."
# 下载pyenv安装脚本
curl https://pyenv.run | bash
# 切换到用户目录
cd "${USER_HOME}"
# 配置pyenv环境变量
cat >> ~/.zshrc << EOF
# 以用户身份下载并安装pyenv
su - $CURRENT_USER << EOF
# 下载pyenv安装脚本
curl -L https://pyenv.run | bash
# 设置环境变量
export PYENV_ROOT="\$HOME/.pyenv"
export PATH="\$PYENV_ROOT/bin:\$PATH"
eval "\$(pyenv init --path)"
eval "\$(pyenv init -)"
eval "\$(pyenv virtualenv-init -)"
EOF
# 备份现有配置
manage_config "backup" "${USER_HOME}/.zshrc"
# 配置pyenv
cat >> "${USER_HOME}/.zshrc" << EOF
# pyenv配置
export PYENV_ROOT="\$HOME/.pyenv"
export PATH="\$PYENV_ROOT/bin:\$PATH"
eval "\$(pyenv init --path)"
eval "\$(pyenv init -)"
eval "\$(pyenv virtualenv-init -)"
EOF
# 重新加载配置
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init --path)"
eval "$(pyenv init -)"
# 确保.pyenv目录权限正确
chown -R $CURRENT_USER:$CURRENT_USER "${USER_HOME}/.pyenv"
log_info "pyenv安装完成"
log_success "pyenv安装完成"
}
# 安装Python
install_python() {
log_info "安装Python..."
# 切换到用户目录
cd "${USER_HOME}"
# 以用户身份运行命令
su - $CURRENT_USER << EOF
# 设置环境变量
export PYENV_ROOT="\$HOME/.pyenv"
export PATH="\$PYENV_ROOT/bin:\$PATH"
eval "\$(pyenv init --path)"
eval "\$(pyenv init -)"
# 安装Python依赖
sudo apt-get install -y make build-essential libssl-dev zlib1g-dev \
libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm \
libncursesw5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev
# 安装最新的Python 3.11
pyenv install 3.11.7
@ -88,14 +98,26 @@ install_python() {
# 验证安装
python --version
EOF
log_info "Python安装完成"
log_success "Python安装完成"
}
# 配置pip
configure_pip() {
log_info "配置pip..."
# 切换到用户目录
cd "${USER_HOME}"
# 以用户身份运行命令
su - $CURRENT_USER << EOF
# 设置环境变量
export PYENV_ROOT="\$HOME/.pyenv"
export PATH="\$PYENV_ROOT/bin:\$PATH"
eval "\$(pyenv init --path)"
eval "\$(pyenv init -)"
# 升级pip
python -m pip install --upgrade pip
@ -104,13 +126,35 @@ configure_pip() {
# 安装pip工具
pip install wheel setuptools
EOF
log_info "pip配置完成"
log_success "pip配置完成"
}
# 安装Python包
# 安装基础Python包
install_python_packages() {
log_info "安装Python包..."
log_info "安装基础Python包..."
# 切换到用户目录
cd "${USER_HOME}"
# 以用户身份运行命令
su - $CURRENT_USER << EOF
# 设置环境变量
export PYENV_ROOT="\$HOME/.pyenv"
export PATH="\$PYENV_ROOT/bin:\$PATH"
eval "\$(pyenv init --path)"
eval "\$(pyenv init -)"
# 创建并激活虚拟环境
python -m venv \$HOME/.venv
source \$HOME/.venv/bin/activate
# 升级pip
python -m pip install --upgrade pip
# 设置pip镜像
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
# 安装开发工具
pip install ipython
@ -126,9 +170,6 @@ install_python_packages() {
# 安装数据处理工具
pip install numpy
pip install pandas
pip install scipy
pip install matplotlib
pip install seaborn
# 安装Web开发工具
pip install django
@ -138,44 +179,126 @@ install_python_packages() {
pip install sqlalchemy
pip install alembic
# 安装机器学习工具
pip install scikit-learn
pip install tensorflow
pip install torch
pip install transformers
# 安装其他工具
pip install requests
pip install python-dotenv
pip install rich
pip install tqdm
log_info "Python包安装完成"
# 退出虚拟环境
deactivate
EOF
# 备份现有配置
manage_config "backup" "${USER_HOME}/.zshrc"
# 添加虚拟环境激活命令到配置文件
cat >> "${USER_HOME}/.zshrc" << EOF
# 激活Python虚拟环境
source \$HOME/.venv/bin/activate 2>/dev/null || true
EOF
log_success "基础Python包安装完成"
}
# 安装机器学习包
install_ml_packages() {
log_info "安装机器学习包..."
# 切换到用户目录
cd "${USER_HOME}"
# 以用户身份运行命令
su - $CURRENT_USER << EOF
# 设置环境变量
export PYENV_ROOT="\$HOME/.pyenv"
export PATH="\$PYENV_ROOT/bin:\$PATH"
eval "\$(pyenv init --path)"
eval "\$(pyenv init -)"
# 激活虚拟环境
source \$HOME/.venv/bin/activate
# 安装科学计算和可视化工具
pip install scipy
pip install matplotlib
pip install seaborn
# 安装机器学习工具
pip install scikit-learn
pip install tensorflow
pip install torch
pip install transformers
# 退出虚拟环境
deactivate
EOF
log_success "机器学习包安装完成"
}
# 配置虚拟环境
configure_venv() {
log_info "配置虚拟环境..."
# 创建虚拟环境目录
mkdir -p ~/.virtualenvs
# 切换到用户目录
cd "${USER_HOME}"
# 安装virtualenvwrapper
# 以用户身份运行命令
su - $CURRENT_USER << EOF
# 设置环境变量
export PYENV_ROOT="\$HOME/.pyenv"
export PATH="\$PYENV_ROOT/bin:\$PATH"
eval "\$(pyenv init --path)"
eval "\$(pyenv init -)"
# 使用主虚拟环境安装virtualenvwrapper
source \$HOME/.venv/bin/activate
pip install virtualenvwrapper
# 配置virtualenvwrapper
cat >> ~/.zshrc << EOF
# virtualenvwrapper配置
export WORKON_HOME=~/.virtualenvs
export PROJECT_HOME=~/projects
source ~/.local/bin/virtualenvwrapper.sh
# 创建必要的目录
mkdir -p \$HOME/.virtualenvs
mkdir -p \$HOME/projects
deactivate
EOF
log_info "虚拟环境配置完成"
# 备份现有配置
manage_config "backup" "${USER_HOME}/.zshrc"
# 配置virtualenvwrapper
cat >> "${USER_HOME}/.zshrc" << EOF
# virtualenvwrapper配置
export WORKON_HOME=\$HOME/.virtualenvs
export PROJECT_HOME=\$HOME/projects
export VIRTUALENVWRAPPER_PYTHON=\$HOME/.venv/bin/python
source \$HOME/.venv/bin/virtualenvwrapper.sh
EOF
# 确保virtualenvwrapper.sh存在
if [ ! -f "${USER_HOME}/.venv/bin/virtualenvwrapper.sh" ]; then
log_error "virtualenvwrapper.sh 不存在,虚拟环境配置可能不完整"
return 1
fi
# 设置正确的权限
chown -R $CURRENT_USER:$CURRENT_USER "${USER_HOME}/.venv"
chmod +x "${USER_HOME}/.venv/bin/virtualenvwrapper.sh"
log_success "虚拟环境配置完成"
}
# 主函数
main() {
# 检查root权限
check_root
# 获取用户信息
get_user_info
# 设置日志
setup_logging
log_info "开始安装Python开发环境..."
# 安装系统依赖
@ -190,15 +313,25 @@ main() {
# 配置pip
configure_pip
# 安装Python包
# 安装基础Python包
install_python_packages
# 配置虚拟环境
configure_venv
log_info "Python开发环境安装完成"
# 询问是否安装机器学习包
read -p "是否安装机器学习相关包?这些包体积较大,安装时间较长。(y/N) " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
install_ml_packages
fi
log_success "Python开发环境安装完成"
log_info "请运行 'source ~/.zshrc' 或重新打开终端以使环境变量生效。"
}
# 设置清理函数
trap cleanup EXIT
# 执行主函数
main

125
scripts/editor/README.md Normal file
View File

@ -0,0 +1,125 @@
# Neovim 编辑器安装和配置
这个目录包含了用于安装和配置 Neovim 编辑器的脚本,以及 NvChad 配置框架。
## 脚本说明
### 1. neovim.sh
用于安装和配置 Neovim 编辑器的主脚本。
#### 主要功能:
- 安装最新版本的 Neovim (v0.10.0+)
- 配置基础的编辑器设置
- 安装必要的依赖Python、Node.js等
- 安装开发工具ripgrep、fd等
- 性能优化配置
#### 使用方法:
```bash
sudo ./neovim.sh
```
#### 性能优化:
- 禁用了不必要的内置插件
- 优化了文件打开和编辑性能
- 配置了更快的搜索引擎
- 优化了UI渲染性能
- 减少了不必要的状态更新
### 2. nvchad.sh
用于安装和配置 NvChad 框架的脚本。
#### 主要功能:
- 安装 NvChad 基础框架
- 配置自定义设置
- 优化插件性能
- 配置按键映射
#### 使用方法:
```bash
sudo ./nvchad.sh
```
#### 性能优化:
- 使用最小化的状态栏主题
- 延迟加载文件树
- 优化了 Treesitter 配置
- 配置了高效的文件搜索
- 禁用了不必要的图标和特效
## 安装后的配置
### 1. 基础配置
- Leader 键设置为空格键
- 使用相对行号
- 启用真彩色支持
- 配置了合理的缩进
- 优化了搜索体验
### 2. 插件配置
- Treesitter智能语法高亮
- MasonLSP 包管理器
- Telescope模糊搜索
- 其他优化插件
### 3. 快捷键
- `<leader>ff`: 查找文件
- `<leader>fg`: 全局搜索
- `<leader>fb`: 查找缓冲区
- `<leader>fh`: 查找帮助文档
## 性能优化建议
### 1. 编辑器启动
- 使用 `nvim --startuptime startup.log` 检查启动时间
- 按需安装语言服务器
- 使用 lazy loading 加载插件
### 2. 大文件处理
- 大文件自动禁用部分功能
- 配置了文件大小限制
- 优化了语法高亮设置
### 3. 插件优化
- 最小化安装必要插件
- 使用异步加载
- 配置了合理的缓存策略
### 4. 系统资源
- 配置了合理的更新时间
- 优化了内存使用
- 减少了不必要的 UI 更新
## 故障排除
### 1. 常见问题
- 如果遇到插件加载错误,运行 `:checkhealth` 检查
- 字体显示问题,确保安装了 Nerd Font
- LSP 服务器问题,使用 `:Mason` 重新安装
### 2. 性能问题
- 如果编辑器变慢,检查 `:TSHighlightCapturesUnderCursor`
- 使用 `:profile start profile.log``:profile func *` 分析性能
- 检查 `:messages` 查看警告和错误
## 维护
### 1. 更新
- 使用 `:TSUpdate` 更新 Treesitter 解析器
- 使用 `:MasonUpdate` 更新 LSP 服务器
- 定期运行 `:checkhealth` 检查系统状态
### 2. 清理
- 使用 `:TSUninstall` 删除不需要的解析器
- 使用 `:Mason` 卸载不需要的 LSP
- 定期清理 `~/.local/share/nvim` 下的缓存
## 贡献
欢迎提交 Issue 和 Pull Request 来改进这些脚本。
## 许可证
MIT License

View File

@ -1,5 +1,8 @@
#!/bin/bash
# 导入公共函数
source "$(dirname "$0")/../utils/common.sh"
# 设置错误时立即退出
set -e
@ -22,9 +25,39 @@ log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# 安装依赖
install_dependencies() {
log_info "安装Neovim依赖..."
# 检查命令是否存在
check_command() {
if ! command -v "$1" &> /dev/null; then
log_error "命令 '$1' 未找到,请先安装"
exit 1
fi
}
# 检查是否为root用户
if [ "$EUID" -ne 0 ]; then
log_error "请使用root权限运行此脚本"
exit 1
fi
# 获取当前用户名
CURRENT_USER=$SUDO_USER
if [ -z "$CURRENT_USER" ]; then
CURRENT_USER=$(who | awk '{print $1}' | head -n1)
fi
# 设置用户主目录
USER_HOME="/home/$CURRENT_USER"
# 检查 Oh My Zsh 是否已安装
if [ ! -d "${USER_HOME}/.oh-my-zsh" ]; then
log_error "Oh My Zsh 未安装,请先运行 zsh.sh"
exit 1
fi
# 安装基础依赖
install_base_dependencies() {
log_info "安装基础依赖..."
apt-get update
apt-get install -y \
ninja-build \
gettext \
@ -32,31 +65,91 @@ install_dependencies() {
unzip \
curl \
git \
nodejs \
npm \
python3-pip \
python3-venv \
ripgrep \
fd-find \
bat \
exa \
delta \
tree
build-essential
# 检查基础命令是否安装成功
check_command git
check_command cmake
check_command python3
check_command pip3
}
# 安装Neovim
install_neovim() {
log_info "安装Neovim..."
# 安装Node.js
install_nodejs() {
log_info "安装Node.js..."
# 检查是否已安装
if command -v node &> /dev/null; then
local current_version=$(node --version)
log_info "Node.js已安装版本: $current_version"
return
fi
# 安装Node.js
mkdir -p /etc/apt/keyrings
rm -f /etc/apt/keyrings/nodesource.gpg
curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg
echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list
# 添加Neovim仓库
add-apt-repository -y ppa:neovim-ppa/unstable
apt-get update
apt-get install -y nodejs
# 安装Neovim
apt-get install -y neovim
# 验证安装
check_command node
check_command npm
log_info "Node.js 版本: $(node --version)"
log_info "npm 版本: $(npm --version)"
}
# 检查neovim版本
check_neovim() {
log_info "检查Neovim是否已安装..."
if ! command -v nvim &> /dev/null; then
return 1
fi
# 检查版本是否 >= 0.10.0
local nvim_version=$(nvim --version | head -n1 | cut -d ' ' -f2)
if [ "$(echo -e "${nvim_version}\n0.10.0" | sort -V | head -n1)" != "0.10.0" ]; then
log_warn "Neovim版本必须 >= 0.10.0,当前版本: ${nvim_version}"
return 1
fi
# 创建配置目录
mkdir -p ~/.config/nvim
return 0
}
# 编译安装neovim
install_neovim() {
log_info "开始编译安装Neovim..."
# 安装编译依赖
apt-get install -y \
ninja-build \
gettext \
cmake \
unzip \
git
# 克隆neovim仓库
cd /tmp
if [ -d "neovim" ]; then
rm -rf neovim
fi
git clone https://github.com/neovim/neovim
cd neovim
# 切换到最新版本
git checkout master
# 编译安装
make CMAKE_BUILD_TYPE=RelWithDebInfo
make install
# 清理
cd ..
rm -rf neovim
}
# 安装Python包
@ -64,101 +157,127 @@ install_python_packages() {
log_info "安装Python包..."
# 创建虚拟环境
python3 -m venv ~/.local/share/nvim/venv
su - $CURRENT_USER -c "python3 -m venv ${USER_HOME}/.local/share/nvim/venv"
# 激活虚拟环境并安装包
source ~/.local/share/nvim/venv/bin/activate
pip install pynvim
pip install black
pip install isort
pip install flake8
pip install mypy
pip install jedi
deactivate
su - $CURRENT_USER -c "source ${USER_HOME}/.local/share/nvim/venv/bin/activate && \
pip install --upgrade pip && \
pip install pynvim black isort flake8 mypy jedi && \
deactivate"
}
# 安装Node.js包
install_node_packages() {
log_info "安装Node.js包..."
# 设置npm全局包安装目录
su - $CURRENT_USER -c "mkdir -p ${USER_HOME}/.npm-global"
su - $CURRENT_USER -c "npm config set prefix '${USER_HOME}/.npm-global'"
# 添加PATH到.zshrc
if ! grep -q "HOME/.npm-global/bin" "${USER_HOME}/.zshrc"; then
echo 'export PATH=~/.npm-global/bin:$PATH' >> "${USER_HOME}/.zshrc"
fi
# 设置环境变量以便立即使用
export PATH="${USER_HOME}/.npm-global/bin:$PATH"
# 安装全局npm包
npm install -g neovim
npm install -g typescript
npm install -g ts-node
npm install -g prettier
npm install -g eslint
su - $CURRENT_USER -c "export PATH=${USER_HOME}/.npm-global/bin:\$PATH && \
npm install -g neovim typescript ts-node prettier eslint"
}
# 配置Neovim
configure_neovim() {
log_info "配置Neovim..."
# 创建配置目录
mkdir -p ${USER_HOME}/.config/nvim
# 创建基本配置
cat > ~/.config/nvim/init.vim << EOF
" 基本设置
set number
set relativenumber
set expandtab
set tabstop=4
set shiftwidth=4
set softtabstop=4
set smartindent
set nowrap
set noswapfile
set nobackup
set undodir=~/.vim/undodir
set undofile
set incsearch
set nohlsearch
set ignorecase
set smartcase
set termguicolors
set scrolloff=8
set signcolumn=yes
set updatetime=50
set colorcolumn=80
set splitright
set splitbelow
cat > ${USER_HOME}/.config/nvim/init.vim << EOF
" 性能优化设置
set nobackup " 禁用备份文件
set nowritebackup " 禁用写入时的备份
set noswapfile " 禁用交换文件
set hidden " 允许在未保存的情况下切换缓冲区
set noshowmode " 不显示当前模式(由状态栏插件显示)
set lazyredraw " 延迟重绘以提高性能
set updatetime=300 " 更新时间间隔默认4000ms太慢
set timeoutlen=500 " 键盘序列等待时间
set synmaxcol=200 " 限制语法高亮的列数以提高性能
set regexpengine=1 " 使用老的正则引擎(更快)
set ttyfast " 指示快速终端连接以优化重绘
" 设置leader键
let mapleader = " "
" 基本UI设置
set number " 显示行号
set relativenumber " 显示相对行号
set signcolumn=yes " 总是显示标记列
set termguicolors " 启用真彩色
set scrolloff=8 " 光标上下保持8行距离
set sidescrolloff=8 " 水平滚动时保持8列距离
set cmdheight=1 " 命令行高度
set shortmess+=c " 不显示补全相关的消息
" 设置文件类型检测
filetype plugin indent on
" 缩进和制表符设置
set expandtab " 使用空格代替制表符
set tabstop=4 " 制表符等于4个空格
set shiftwidth=4 " 缩进等于4个空格
set softtabstop=4 " 退格键一次删除4个空格
set smartindent " 智能缩进
" 设置语法高亮
syntax enable
" 搜索设置
set ignorecase " 搜索忽略大小写
set smartcase " 智能大小写搜索
set incsearch " 增量搜索
set nohlsearch " 不高亮搜索结果
" 设置编码
" 编码设置
set encoding=utf-8
set fileencoding=utf-8
set termencoding=utf-8
" 设置状态栏
set laststatus=2
set statusline=%F%m%r%h%w\ [FORMAT=%{&ff}]\ [TYPE=%Y]\ [POS=%l,%v][%p%%]\ %{strftime(\"%d/%m/%y\ -\ %H:%M\")}
" 设置命令模式补全
set wildmenu
set wildmode=list:longest,full
" 设置历史记录
set history=1000
set undolevels=1000
" 设置鼠标支持
set mouse=a
" 设置剪贴板
" 系统剪贴板集成
set clipboard=unnamedplus
" 设置自动补全
set completeopt=menu,menuone,noselect
" 文件类型设置
filetype plugin indent on
syntax enable
" 设置终端颜色
set t_Co=256
set background=dark
" 设置leader键
let mapleader = " "
" 创建必要的目录
if !isdirectory(expand('~/.local/share/nvim/backup'))
silent! call mkdir(expand('~/.local/share/nvim/backup'), 'p')
endif
" 性能相关的全局变量
let g:loaded_matchparen = 1 " 禁用括号匹配(提高性能)
let g:loaded_matchit = 1 " 禁用扩展的%匹配
let g:loaded_logiPat = 1 " 禁用逻辑模式插件
let g:loaded_rrhelper = 1 " 禁用远程插件帮助
let g:loaded_tarPlugin = 1 " 禁用tar文件插件
let g:loaded_gzip = 1 " 禁用gzip插件
let g:loaded_zipPlugin = 1 " 禁用zip插件
let g:loaded_2html_plugin = 1 " 禁用2html插件
let g:loaded_shada_plugin = 1 " 禁用shada插件
let g:loaded_spellfile_plugin = 1 " 禁用拼写文件插件
let g:loaded_netrw = 1 " 禁用netrw
let g:loaded_netrwPlugin = 1 " 禁用netrw插件
let g:loaded_tutor_mode_plugin = 1 " 禁用教程插件
let g:loaded_remote_plugins = 1 " 禁用远程插件
" 文件类型特定的性能优化
augroup performance_optimizations
autocmd!
" 大文件打开时禁用某些功能
autocmd BufReadPre * let f=getfsize(expand("<afile>")) | if f > 100000 || f == -2 | set eventignore+=FileType | setlocal noswapfile bufhidden=unload buftype=nowrite undolevels=-1 | else | set eventignore-=FileType | endif
augroup END
EOF
# 设置权限
chown -R $CURRENT_USER:$CURRENT_USER ${USER_HOME}/.config/nvim
}
# 安装语言服务器
@ -166,39 +285,190 @@ install_language_servers() {
log_info "安装语言服务器..."
# 安装各种语言的LSP服务器
npm install -g typescript-language-server
npm install -g vscode-langservers-extracted
npm install -g @tailwindcss/language-server
npm install -g @prisma/language-server
npm install -g graphql-language-service-cli
npm install -g vscode-html-languageserver-bin
npm install -g vscode-css-languageserver-bin
npm install -g vscode-json-languageserver-bin
npm install -g vscode-eslint-language-server
npm install -g @typescript-eslint/parser
npm install -g @typescript-eslint/eslint-plugin
npm install -g eslint_d
npm install -g prettier
npm install -g stylelint
npm install -g markdownlint-cli
npm install -g yaml-language-server
npm install -g dockerfile-language-server-nodejs
npm install -g bash-language-server
npm install -g vscode-langservers-extracted
su - $CURRENT_USER -c "export PATH=${USER_HOME}/.npm-global/bin:\$PATH && \
npm install -g \
typescript-language-server \
vscode-langservers-extracted \
eslint \
prettier \
bash-language-server"
}
# 主函数
main() {
log_info "开始安装Neovim..."
# 删除旧版本vi
remove_old_vi() {
log_info "检查并删除旧版本vi..."
# 安装依赖
install_dependencies
# 检查是否安装了vim或vi
if dpkg -l | grep -qw "vim\|vi"; then
log_info "发现旧版本编辑器,正在删除..."
apt-get remove -y vim vim-runtime vim-tiny vim-common vim-gui-common
apt-get autoremove -y
# 删除vim配置
if [ -d "${USER_HOME}/.vim" ]; then
mv "${USER_HOME}/.vim" "${USER_HOME}/.vim.bak.$(date +%Y%m%d_%H%M%S)"
fi
if [ -f "${USER_HOME}/.vimrc" ]; then
mv "${USER_HOME}/.vimrc" "${USER_HOME}/.vimrc.bak.$(date +%Y%m%d_%H%M%S)"
fi
else
log_info "未发现旧版本编辑器"
fi
}
# 安装额外的开发工具
install_dev_tools() {
log_info "安装开发工具..."
# 安装Neovim
install_neovim
# 安装通用开发工具
apt-get install -y \
ripgrep \
fd-find \
universal-ctags \
shellcheck \
yamllint
# 创建fd-find软链接
ln -sf $(which fdfind) /usr/local/bin/fd
}
# 配置Python环境
setup_python_env() {
log_info "配置Python环境..."
# 安装Python开发工具
apt-get install -y \
python3-dev \
python3-pip \
python3-venv
# 创建虚拟环境
su - $CURRENT_USER -c "python3 -m venv ${USER_HOME}/.local/share/nvim/venv"
# 安装Python包
install_python_packages
su - $CURRENT_USER -c "source ${USER_HOME}/.local/share/nvim/venv/bin/activate && \
pip install --upgrade pip && \
pip install \
pynvim \
black \
isort \
flake8 \
mypy \
jedi \
pylint \
rope \
debugpy && \
deactivate"
}
# 卸载并清理neovim
uninstall_neovim() {
log_info "卸载并清理Neovim..."
# 停止所有neovim进程
if pgrep -f nvim > /dev/null; then
log_info "停止所有Neovim进程..."
pkill -f nvim
fi
# 卸载neovim包
if dpkg -l | grep -q neovim; then
log_info "卸载Neovim包..."
apt-get remove --purge -y neovim
apt-get autoremove -y
fi
# 删除neovim相关目录和文件
log_info "清理Neovim相关文件..."
# 系统级文件
if [ -d "/opt/nvim" ]; then
rm -rf /opt/nvim
fi
if [ -f "/usr/local/bin/nvim" ]; then
rm -f /usr/local/bin/nvim
fi
if [ -d "/usr/local/share/nvim" ]; then
rm -rf /usr/local/share/nvim
fi
if [ -d "/usr/local/lib/nvim" ]; then
rm -rf /usr/local/lib/nvim
fi
if [ -d "/usr/local/lib/lua/5.1/nvim" ]; then
rm -rf /usr/local/lib/lua/5.1/nvim
fi
if [ -d "/usr/local/lib/lua/5.4/nvim" ]; then
rm -rf /usr/local/lib/lua/5.4/nvim
fi
# 用户级文件
if [ -d "${USER_HOME}/.config/nvim" ]; then
rm -rf "${USER_HOME}/.config/nvim"
fi
if [ -d "${USER_HOME}/.local/share/nvim" ]; then
rm -rf "${USER_HOME}/.local/share/nvim"
fi
if [ -d "${USER_HOME}/.local/share/lazy" ]; then
rm -rf "${USER_HOME}/.local/share/lazy"
fi
if [ -d "${USER_HOME}/.local/state/nvim" ]; then
rm -rf "${USER_HOME}/.local/state/nvim"
fi
if [ -d "${USER_HOME}/.cache/nvim" ]; then
rm -rf "${USER_HOME}/.cache/nvim"
fi
# 确保目录权限正确
log_info "修复目录权限..."
if [ -d "${USER_HOME}/.config" ]; then
chown -R ${CURRENT_USER}:${CURRENT_USER} "${USER_HOME}/.config"
fi
if [ -d "${USER_HOME}/.local" ]; then
chown -R ${CURRENT_USER}:${CURRENT_USER} "${USER_HOME}/.local"
fi
if [ -d "${USER_HOME}/.cache" ]; then
chown -R ${CURRENT_USER}:${CURRENT_USER} "${USER_HOME}/.cache"
fi
log_success "Neovim已完全卸载并清理"
}
# 更新主函数
main() {
# 检查root权限
check_root
# 获取用户信息
get_user_info
# 卸载并清理旧版本neovim
uninstall_neovim
# 删除旧版本vi
remove_old_vi
# 安装基础依赖
install_base_dependencies
# 检查neovim版本
if ! check_neovim; then
log_info "Neovim未安装或版本不符合要求开始编译安装..."
if ! install_neovim; then
log_error "Neovim安装失败"
exit 1
fi
else
log_success "Neovim已安装且版本符合要求"
fi
# 安装开发工具
install_dev_tools
# 安装Node.js
install_nodejs
# 配置Python环境
setup_python_env
# 安装Node.js包
install_node_packages
@ -209,9 +479,23 @@ main() {
# 安装语言服务器
install_language_servers
log_info "Neovim安装完成"
log_info "请运行 nvim 来启动编辑器。"
log_info "首次启动时会自动安装插件。"
log_success "Neovim安装完成"
log_info "请运行以下命令使环境变量生效:"
log_info "source ~/.zshrc"
log_info "然后运行 nvim 来启动编辑器。"
# 显示安装的工具版本
log_info "已安装的工具版本:"
nvim --version | head -n1
node --version
npm --version
python3 --version
if command -v rg &> /dev/null; then
rg --version | head -n1
fi
if command -v fd &> /dev/null; then
fd --version
fi
}
# 执行主函数

File diff suppressed because it is too large Load Diff

View File

@ -1,60 +1,52 @@
#!/bin/bash
# 设置错误时立即退出
set -e
# 导入通用函数
source "$(dirname "$0")/../utils/common.sh"
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# 检查root权限
check_root
# 日志函数
log_info() {
echo -e "${GREEN}[INFO]${NC} $1"
# 检查Docker是否已安装
check_docker() {
if ! command -v docker &> /dev/null; then
log_info "Docker未安装正在安装..."
install_docker
else
log_info "Docker已安装"
fi
}
log_warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# 安装Docker和Docker Compose
# 安装Docker
install_docker() {
log_info "安装Docker和Docker Compose..."
# 安装Docker
log_info "安装Docker..."
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
rm get-docker.sh
# 安装Docker Compose
sudo curl -L "https://github.com/docker/compose/releases/download/v2.24.5/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
# 将当前用户添加到docker组
sudo usermod -aG docker $USER
log_info "Docker和Docker Compose安装完成"
log_info "Docker安装完成"
}
# 克隆DNMP仓库
clone_dnmp() {
log_info "克隆DNMP仓库..."
# 创建项目目录
mkdir -p ~/projects
cd ~/projects
# 创建安装目录
sudo mkdir -p /opt/dnmp
# 如果目录已存在且不为空,则清理
if [ -d "/opt/dnmp" ] && [ "$(ls -A /opt/dnmp)" ]; then
log_info "清理已存在的DNMP目录..."
sudo rm -rf /opt/dnmp/*
fi
# 克隆DNMP仓库
git clone https://github.com/yeszao/dnmp.git
cd dnmp
sudo git clone https://github.com/garymengcom/dnmp.git /opt/dnmp
# 复制环境配置文件
cp env.sample .env
# 设置目录权限
sudo chown -R $USER:$USER /opt/dnmp
log_info "DNMP仓库克隆完成"
}
@ -63,7 +55,11 @@ clone_dnmp() {
configure_dnmp() {
log_info "配置DNMP..."
cd ~/projects/dnmp
cd /opt/dnmp
# 复制配置文件
cp docker-compose.sample.yml docker-compose.yml
cp env.sample .env
# 修改.env文件
sed -i 's/PHP_VERSION=7.4/PHP_VERSION=8.2/' .env
@ -86,7 +82,7 @@ EOF
start_dnmp() {
log_info "启动DNMP..."
cd ~/projects/dnmp
cd /opt/dnmp
# 启动服务
docker-compose up -d
@ -100,37 +96,36 @@ start_dnmp() {
log_info "DNMP启动完成"
}
# 配置PHP开发环境
configure_php_dev() {
log_info "配置PHP开发环境..."
# 创建别名文件
create_alias_file() {
log_info "创建命令别名文件..."
# 安装Composer
curl -sS https://getcomposer.org/installer | php
sudo mv composer.phar /usr/local/bin/composer
# 配置Composer镜像
composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/
# 安装PHP开发工具
composer global require phpunit/phpunit
composer global require squizlabs/php_codesniffer
composer global require friendsofphp/php-cs-fixer
# 添加Composer全局bin目录到PATH
cat >> ~/.zshrc << EOF
# Composer配置
export PATH="\$HOME/.composer/vendor/bin:\$PATH"
cat > /opt/dnmp/bash.alias << EOF
# PHP开发环境别名
alias dphp='docker exec -it php82 bash'
alias dcomposer='docker exec -it php82 composer'
alias dphpunit='docker exec -it php82 phpunit'
alias dphpcs='docker exec -it php82 phpcs'
alias dphpcbf='docker exec -it php82 phpcbf'
EOF
log_info "PHP开发环境配置完成"
# 添加别名到用户shell配置
if [ -f ~/.zshrc ]; then
echo "source /opt/dnmp/bash.alias" >> ~/.zshrc
elif [ -f ~/.bashrc ]; then
echo "source /opt/dnmp/bash.alias" >> ~/.bashrc
fi
log_info "命令别名文件创建完成"
log_info "请运行 'source ~/.zshrc' 或 'source ~/.bashrc' 使别名生效"
}
# 主函数
main() {
log_info "开始安装PHP开发环境..."
# 安装Docker和Docker Compose
install_docker
# 检查并安装Docker
check_docker
# 克隆DNMP仓库
clone_dnmp
@ -141,14 +136,20 @@ main() {
# 启动DNMP
start_dnmp
# 配置PHP开发环境
configure_php_dev
# 创建别名文件
create_alias_file
log_info "PHP开发环境安装完成"
log_info "请运行 'source ~/.zshrc' 或重新打开终端以使环境变量生效。"
log_info "PHP环境安装完成"
log_info "访问 http://localhost 查看PHP信息页面。"
log_info "默认MySQL密码123456"
log_info "默认Redis密码123456"
log_info "DNMP安装目录/opt/dnmp"
log_info ""
log_info "如需手动安装Composer请执行以下步骤"
log_info "1. 进入PHP容器: dphp"
log_info "2. 下载Composer: curl -sS https://getcomposer.org/installer | php"
log_info "3. 安装Composer: mv composer.phar /usr/local/bin/composer"
log_info "4. 配置镜像: composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/"
}
# 执行主函数

98
scripts/shell/README.md Normal file
View File

@ -0,0 +1,98 @@
# Shell 环境配置脚本
本目录包含用于配置和管理Shell环境的脚本集合。这些脚本主要用于设置Zsh环境、安装插件、配置系统环境变量等。
## 目录结构
```
shell/
├── README.md # 本文档
├── zsh.sh # Zsh环境配置脚本
├── plugins.sh # Zsh插件管理脚本
└── config.sh # 环境变量和别名配置脚本
```
## 脚本说明
### zsh.sh
Zsh环境配置脚本用于安装和配置Zsh环境。
#### 功能
- 安装Zsh和Oh My Zsh
- 安装Powerlevel10k主题
- 安装Nerd Fonts字体
- 配置基础Zsh设置
#### 使用方法
```bash
sudo ./zsh.sh
```
### plugins.sh
Zsh插件管理脚本用于安装和管理各种Zsh插件。
#### 功能
- 安装autojump快速目录跳转
- 安装fzf模糊查找
- 安装zsh-nvmNode.js版本管理
- 安装pyenvPython版本管理
- 配置插件相关设置
#### 使用方法
```bash
sudo ./plugins.sh
```
### config.sh
环境变量和别名配置脚本,用于设置系统环境变量和常用命令别名。
#### 功能
- 配置系统环境变量
- 设置常用命令别名
- 配置终端显示
- 设置历史记录
- 配置目录栈
- 设置终端标题
#### 使用方法
```bash
sudo ./config.sh
```
## 依赖要求
- Debian/Ubuntu系统
- sudo权限
- 网络连接(用于下载插件和主题)
## 安装顺序
1. 首先运行 `zsh.sh` 安装基础Zsh环境
2. 重新打开终端或运行 `source ~/.zshrc`
3. 运行 `plugins.sh` 安装插件
4. 运行 `config.sh` 配置环境变量和别名
## 注意事项
- 所有脚本需要sudo权限运行
- 安装过程中需要网络连接
- 如果遇到网络问题,脚本会自动尝试使用镜像源
- 所有操作都有日志记录,保存在 `~/.logs` 目录下
## 常见问题
1. 如果安装过程中断,可以重新运行相应的脚本
2. 如果遇到权限问题确保使用sudo运行脚本
3. 如果插件安装失败,检查网络连接并重试
4. 如果配置不生效,运行 `source ~/.zshrc` 重新加载配置
## 更新日志
### v1.0.0 (2024-03-xx)
- 初始版本发布
- 完成基础Zsh环境配置
- 实现插件管理系统
- 添加环境变量配置

View File

@ -1,5 +1,8 @@
#!/bin/bash
# 导入公共函数
source "$(dirname "$0")/../utils/common.sh"
# 设置错误时立即退出
set -e
@ -22,114 +25,164 @@ log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# 安装zsh-autosuggestions
install_zsh_autosuggestions() {
log_info "安装zsh-autosuggestions..."
git clone https://github.com/zsh-users/zsh-autosuggestions ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestions
}
# 检查是否为root用户
if [ "$EUID" -ne 0 ]; then
log_error "请使用root权限运行此脚本"
exit 1
fi
# 安装zsh-syntax-highlighting
install_zsh_syntax_highlighting() {
log_info "安装zsh-syntax-highlighting..."
git clone https://github.com/zsh-users/zsh-syntax-highlighting.git ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting
}
# 获取当前用户名
CURRENT_USER=$SUDO_USER
if [ -z "$CURRENT_USER" ]; then
CURRENT_USER=$(who | awk '{print $1}' | head -n1)
fi
# 安装zsh-completions
install_zsh_completions() {
log_info "安装zsh-completions..."
git clone https://github.com/zsh-users/zsh-completions ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-completions
# 设置用户主目录
USER_HOME="/home/$CURRENT_USER"
ZSH_CUSTOM="${USER_HOME}/.oh-my-zsh/custom"
# 检查 Oh My Zsh 是否已安装
check_oh_my_zsh() {
if [ ! -d "${USER_HOME}/.oh-my-zsh" ]; then
log_error "Oh My Zsh 未安装,请先运行 zsh.sh"
exit 1
fi
}
# 安装autojump
install_autojump() {
log_info "安装autojump..."
apt-get install -y autojump
show_progress "安装 autojump"
ensure_package "autojump"
# 确保 autojump 数据目录存在
ensure_dir "/usr/share/autojump" "root:root"
ensure_dir "${USER_HOME}/.local/share/autojump" "$CURRENT_USER:$CURRENT_USER"
update_progress "安装 autojump" "完成"
}
# 安装fzf
install_fzf() {
log_info "安装fzf..."
apt-get install -y fzf
show_progress "安装 fzf"
ensure_package "fzf"
update_progress "安装 fzf" "完成"
}
# 安装zsh-nvm
install_zsh_nvm() {
log_info "安装zsh-nvm..."
git clone https://github.com/lukechilds/zsh-nvm ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-nvm
show_progress "安装 zsh-nvm"
local nvm_dir="${ZSH_CUSTOM}/plugins/zsh-nvm"
local nvm_url="https://github.com/lukechilds/zsh-nvm"
manage_plugin "zsh-nvm" "$nvm_dir" "$nvm_url"
}
# 安装pyenv
install_pyenv() {
log_info "安装pyenv..."
curl https://pyenv.run | bash
show_progress "安装 pyenv"
if [ ! -d "${USER_HOME}/.pyenv" ]; then
local install_url="https://pyenv.run"
local temp_script="/tmp/pyenv_installer.sh"
if download_file "$install_url" "$temp_script"; then
su - $CURRENT_USER -c "bash $temp_script"
rm -f "$temp_script"
update_progress "安装 pyenv" "完成"
else
update_progress "安装 pyenv" "失败"
return 1
fi
else
update_progress "安装 pyenv" "已存在"
fi
}
# 配置fzf
configure_fzf() {
log_info "配置fzf..."
# 配置插件
configure_plugins() {
show_progress "配置插件"
# 安装fzf键绑定和补全
$(brew --prefix)/opt/fzf/install --all
# 备份现有配置
manage_config "backup" "${USER_HOME}/.zshrc"
# 添加fzf配置到.zshrc
cat >> ~/.zshrc << EOF
# 添加 autojump 配置
cat >> "${USER_HOME}/.zshrc" << 'EOF'
# autojump配置
if [ -f /usr/share/autojump/autojump.zsh ]; then
. /usr/share/autojump/autojump.zsh
fi
EOF
# 添加 fzf 配置
cat >> "${USER_HOME}/.zshrc" << 'EOF'
# fzf配置
if [ -f ~/.fzf.zsh ]; then
source ~/.fzf.zsh
fi
export FZF_DEFAULT_OPTS='--height 40% --layout=reverse --border'
export FZF_DEFAULT_COMMAND='fd --type f'
export FZF_CTRL_T_COMMAND='\$FZF_DEFAULT_COMMAND'
export FZF_CTRL_T_OPTS="--preview 'bat --color=always --line-range=:500 {}'"
export FZF_DEFAULT_COMMAND='find . -type f'
export FZF_CTRL_T_COMMAND="$FZF_DEFAULT_COMMAND"
export FZF_CTRL_T_OPTS="--preview 'cat {}'"
export FZF_CTRL_R_OPTS="--preview 'echo {}' --preview-window down:3:hidden:wrap --bind '?:toggle-preview'"
export FZF_ALT_C_OPTS="--preview 'tree -C {} | head -200'"
EOF
}
# 配置pyenv
configure_pyenv() {
log_info "配置pyenv..."
# 添加pyenv配置到.zshrc
cat >> ~/.zshrc << EOF
# 添加 pyenv 配置
cat >> "${USER_HOME}/.zshrc" << 'EOF'
# pyenv配置
export PYENV_ROOT="\$HOME/.pyenv"
command -v pyenv >/dev/null || export PATH="\$PYENV_ROOT/bin:\$PATH"
eval "\$(pyenv init -)"
export PYENV_ROOT="$HOME/.pyenv"
command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"
EOF
}
# 配置autojump
configure_autojump() {
log_info "配置autojump..."
# 更新插件列表
local zshrc="${USER_HOME}/.zshrc"
sed -i '/^plugins=(/,/^)/ c\plugins=(\n git\n docker\n docker-compose\n npm\n node\n python\n pip\n zsh-autosuggestions\n zsh-syntax-highlighting\n autojump\n fzf\n zsh-nvm\n)' "$zshrc"
# 添加autojump配置到.zshrc
cat >> ~/.zshrc << EOF
# autojump配置
. /usr/share/autojump/autojump.sh
EOF
update_progress "配置插件" "完成"
}
# 主函数
main() {
log_info "开始安装Zsh插件..."
# 检查root权限
check_root
# 获取用户信息
get_user_info
# 设置日志
setup_logging
# 设置 ZSH_CUSTOM 变量
ZSH_CUSTOM="${USER_HOME}/.oh-my-zsh/custom"
# 检查 Oh My Zsh
check_oh_my_zsh
# 检查依赖
check_dependencies "git" "curl" "wget" "zsh" "sudo"
# 安装插件
install_zsh_autosuggestions
install_zsh_syntax_highlighting
install_zsh_completions
install_autojump
install_fzf
install_zsh_nvm
install_pyenv
# 配置插件
configure_fzf
configure_pyenv
configure_autojump
configure_plugins
log_info "Zsh插件安装完成"
log_info "请重新加载.zshrc以应用更改source ~/.zshrc"
# 设置权限
show_progress "设置权限"
chown -R $CURRENT_USER:$CURRENT_USER ${USER_HOME}/.oh-my-zsh
chown -R $CURRENT_USER:$CURRENT_USER ${USER_HOME}/.zshrc
chown -R $CURRENT_USER:$CURRENT_USER ${USER_HOME}/.pyenv
update_progress "设置权限" "完成"
log_success "Zsh插件安装完成"
log_info "请运行以下命令使配置生效:"
log_info "source ~/.zshrc"
}
# 执行主函数

View File

@ -1,84 +1,91 @@
#!/bin/bash
# 设置错误时立即退出
set -e
# 日志函数
log_info() {
echo "[INFO] $1"
}
log_warn() {
echo "[WARN] $1"
}
log_error() {
echo "[ERROR] $1"
}
# 检查是否为root用户
if [ "$EUID" -ne 0 ]; then
log_error "请使用root权限运行此脚本"
exit 1
fi
# 获取当前用户名
CURRENT_USER=$SUDO_USER
if [ -z "$CURRENT_USER" ]; then
CURRENT_USER=$(who | awk '{print $1}' | head -n1)
fi
# 设置用户主目录
USER_HOME="/home/$CURRENT_USER"
# 更新系统包
log_info "更新系统包..."
apt-get update
apt-get upgrade -y
# 安装必要的依赖
log_info "安装必要的依赖..."
apt-get install -y \
git \
curl \
wget \
build-essential \
zsh \
sudo \
fontconfig
# 导入公共函数
source "$(dirname "$0")/../utils/common.sh"
# 安装 Oh My Zsh
log_info "安装 Oh My Zsh..."
# 删除已存在的 Oh My Zsh 目录
if [ -d "${USER_HOME}/.oh-my-zsh" ]; then
log_info "删除已存在的 Oh My Zsh 目录..."
rm -rf ${USER_HOME}/.oh-my-zsh
fi
install_oh_my_zsh() {
show_progress "安装 Oh My Zsh"
# 删除已存在的 Oh My Zsh 目录
if [ -d "${USER_HOME}/.oh-my-zsh" ]; then
if confirm "检测到已存在的 Oh My Zsh 安装,是否重新安装?"; then
log_info "删除已存在的 Oh My Zsh 目录..."
rm -rf ${USER_HOME}/.oh-my-zsh
else
update_progress "安装 Oh My Zsh" "已跳过"
return 0
fi
fi
# 获取安装脚本URL可能使用镜像
local install_url="https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh"
local mirror_url=$(get_mirror_url "$install_url" "omz")
# 安装 Oh My Zsh
su - $CURRENT_USER -c "curl -fsSL $mirror_url | sh -s -- --unattended"
# 设置 zsh 为默认 shell
show_progress "设置 zsh 为默认 shell"
chsh -s $(which zsh) $CURRENT_USER
update_progress "设置 zsh 为默认 shell" "完成"
}
# 切换到用户目录
cd ${USER_HOME}
# 安装主题和字体
install_theme_and_fonts() {
show_progress "安装 Powerlevel10k 主题"
local theme_url="https://github.com/romkatv/powerlevel10k.git"
local theme_dir="${USER_HOME}/.oh-my-zsh/custom/themes/powerlevel10k"
manage_plugin "powerlevel10k" "$theme_dir" "$theme_url"
# 安装 MesloLGS NF 字体
local font_urls=(
"https://github.com/romkatv/powerlevel10k-media/raw/master/MesloLGS%20NF%20Regular.ttf"
"https://github.com/romkatv/powerlevel10k-media/raw/master/MesloLGS%20NF%20Bold.ttf"
"https://github.com/romkatv/powerlevel10k-media/raw/master/MesloLGS%20NF%20Italic.ttf"
"https://github.com/romkatv/powerlevel10k-media/raw/master/MesloLGS%20NF%20Bold%20Italic.ttf"
)
show_progress "安装字体"
for url in "${font_urls[@]}"; do
local font_name=$(basename "$url" | sed 's/%20/ /g')
install_font "$url" "$font_name"
done
update_progress "安装字体" "完成"
}
# 安装 Oh My Zsh
su - $CURRENT_USER -c 'sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" "" --unattended'
# 安装基础插件
install_base_plugins() {
show_progress "安装基础插件"
local plugins_dir="${USER_HOME}/.oh-my-zsh/custom/plugins"
# 定义插件
local plugins=(
"zsh-autosuggestions:https://github.com/zsh-users/zsh-autosuggestions"
"zsh-syntax-highlighting:https://github.com/zsh-users/zsh-syntax-highlighting.git"
)
# 安装每个插件
for plugin in "${plugins[@]}"; do
local name="${plugin%%:*}"
local url="${plugin#*:}"
manage_plugin "$name" "${plugins_dir}/${name}" "$url"
done
update_progress "安装基础插件" "完成"
}
# 设置 zsh 为默认 shell
log_info "设置 zsh 为默认 shell..."
chsh -s $(which zsh) $CURRENT_USER
# 安装常用插件
log_info "安装常用插件..."
su - $CURRENT_USER -c "git clone https://github.com/zsh-users/zsh-autosuggestions ${USER_HOME}/.oh-my-zsh/custom/plugins/zsh-autosuggestions"
su - $CURRENT_USER -c "git clone https://github.com/zsh-users/zsh-syntax-highlighting.git ${USER_HOME}/.oh-my-zsh/custom/plugins/zsh-syntax-highlighting"
# 配置 .zshrc
log_info "配置 .zshrc..."
# 备份现有的 .zshrc 文件
if [ -f "${USER_HOME}/.zshrc" ]; then
log_info "备份现有的 .zshrc 文件..."
mv ${USER_HOME}/.zshrc ${USER_HOME}/.zshrc.backup
fi
cat > ${USER_HOME}/.zshrc << 'EOL'
# 配置 Zsh
configure_zsh() {
show_progress "配置 Zsh"
# 备份现有配置
manage_config "backup" "${USER_HOME}/.zshrc"
# 创建新的配置文件
cat > ${USER_HOME}/.zshrc << 'EOL'
# Enable Powerlevel10k instant prompt
if [[ -r "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" ]]; then
source "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh"
@ -108,8 +115,6 @@ source $ZSH/oh-my-zsh.sh
# User configuration
export LANG=en_US.UTF-8
export EDITOR='vim'
export VISUAL='vim'
# 设置自动补全快捷键为逗号
bindkey ',' autosuggest-accept
@ -132,61 +137,79 @@ autoload -Uz compinit && compinit
zstyle ':completion:*' menu select
zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}'
# Aliases
alias ll='ls -la'
alias ..='cd ..'
alias ...='cd ../..'
alias ....='cd ../../..'
alias grep='grep --color=auto'
alias mkdir='mkdir -pv'
alias wget='wget -c'
alias hist='history | grep'
alias ports='netstat -tulanp'
alias path='echo -e ${PATH//:/\\n}'
alias now='date +"%T"'
alias nowdate='date +"%d-%m-%Y"'
alias update='sudo apt-get update'
alias upgrade='sudo apt-get upgrade'
alias meminfo='free -m -l -t'
alias psmem='ps auxf | sort -nr -k 4'
alias pscpu='ps auxf | sort -nr -k 3'
alias wget='wget -c'
alias getpass="openssl rand -base64 20"
alias sha1='openssl sha1'
alias ping='ping -c 5'
alias mkdir='mkdir -pv'
alias diff='colordiff'
alias mount='mount |column -t'
alias h='history'
alias j='jobs -l'
alias vi=vim
alias svi='sudo vim'
alias vis='vim "+set si"'
alias edit='vim'
# To customize prompt, run `p10k configure` or edit ~/.p10k.zsh.
[[ ! -f ~/.p10k.zsh ]] || source ~/.p10k.zsh
EOL
# 安装 Powerlevel10k 主题
log_info "安装 Powerlevel10k 主题..."
su - $CURRENT_USER -c "git clone --depth=1 https://github.com/romkatv/powerlevel10k.git ${USER_HOME}/.oh-my-zsh/custom/themes/powerlevel10k"
# 添加常用别名
local aliases=(
"ll:ls -la"
"..:cd .."
"...:cd ../.."
"....:cd ../../.."
"update:sudo apt-get update"
"upgrade:sudo apt-get upgrade"
"vi:nvim"
"vim:nvim"
"edit:nvim"
)
for alias_pair in "${aliases[@]}"; do
local name="${alias_pair%%:*}"
local value="${alias_pair#*:}"
add_alias "$name" "$value" "${USER_HOME}/.zshrc"
done
# 设置编辑器
add_env_var "EDITOR" "nvim" "${USER_HOME}/.zshrc"
add_env_var "VISUAL" "nvim" "${USER_HOME}/.zshrc"
update_progress "配置 Zsh" "完成"
}
# 安装字体
log_info "安装字体..."
su - $CURRENT_USER -c "mkdir -p ${USER_HOME}/.local/share/fonts"
su - $CURRENT_USER -c "cd ${USER_HOME}/.local/share/fonts && curl -LO https://github.com/romkatv/powerlevel10k-media/raw/master/MesloLGS%20NF%20Regular.ttf"
su - $CURRENT_USER -c "cd ${USER_HOME}/.local/share/fonts && curl -LO https://github.com/romkatv/powerlevel10k-media/raw/master/MesloLGS%20NF%20Bold.ttf"
su - $CURRENT_USER -c "cd ${USER_HOME}/.local/share/fonts && curl -LO https://github.com/romkatv/powerlevel10k-media/raw/master/MesloLGS%20NF%20Italic.ttf"
su - $CURRENT_USER -c "cd ${USER_HOME}/.local/share/fonts && curl -LO https://github.com/romkatv/powerlevel10k-media/raw/master/MesloLGS%20NF%20Bold%20Italic.ttf"
su - $CURRENT_USER -c "fc-cache -f -v"
# 主函数
main() {
# 检查root权限
check_root
# 获取用户信息
get_user_info
# 设置日志
setup_logging
# 检查依赖
check_dependencies "git" "curl" "wget" "zsh" "sudo"
# 安装基础依赖
install_base_dependencies
# 安装 zsh
ensure_package "zsh"
# 安装 Oh My Zsh
install_oh_my_zsh
# 安装主题和字体
install_theme_and_fonts
# 安装基础插件
install_base_plugins
# 配置 Zsh
configure_zsh
# 设置权限
show_progress "设置权限"
chown -R $CURRENT_USER:$CURRENT_USER ${USER_HOME}/.oh-my-zsh
chown -R $CURRENT_USER:$CURRENT_USER ${USER_HOME}/.zshrc
chown -R $CURRENT_USER:$CURRENT_USER ${USER_HOME}/.local
update_progress "设置权限" "完成"
log_success "Zsh 环境配置完成!"
log_info "请重新打开终端或运行 'source ~/.zshrc' 使配置生效"
log_info "首次登录后,运行 p10k configure 来配置 Powerlevel10k 主题"
}
# 设置权限
log_info "设置权限..."
chown -R $CURRENT_USER:$CURRENT_USER ${USER_HOME}/.oh-my-zsh
chown -R $CURRENT_USER:$CURRENT_USER ${USER_HOME}/.zshrc
chown -R $CURRENT_USER:$CURRENT_USER ${USER_HOME}/.local
log_info "Zsh 环境配置完成!"
log_info "请重新打开终端或运行 'source ~/.zshrc' 使配置生效"
log_info "首次登录后,运行 p10k configure 来配置 Powerlevel10k 主题"
# 执行主函数
main

119
scripts/system/README.md Normal file
View File

@ -0,0 +1,119 @@
# 系统环境检查与配置脚本
本目录包含用于检查和配置Windows WSL环境的脚本集合。这些脚本主要用于检查WSL环境状态、安装Debian系统等。
## 目录结构
```
system/
├── README.md # 本文档
├── check-wsl.bat # Windows批处理脚本检查WSL环境
├── check-wsl.ps1 # PowerShell脚本检查WSL环境
├── install-debian.bat # Windows批处理脚本安装Debian
├── install-debian.ps1 # PowerShell脚本安装Debian
├── run-check-wsl-ps.bat # 运行WSL检查脚本的批处理
└── run-install-debian-ps.bat # 运行Debian安装脚本的批处理
```
## 脚本说明
### check-wsl.bat/ps1
检查Windows WSL环境的脚本。
#### 功能
- 检查Windows版本
- 检查WSL安装状态
- 检查WSL2是否启用
- 检查Debian安装状态
- 检查虚拟化状态
- 检查必要的Windows功能
#### 使用方法
```batch
# 使用批处理脚本
check-wsl.bat
# 使用PowerShell脚本
.\check-wsl.ps1
```
### install-debian.bat/ps1
安装Debian系统的脚本。
#### 功能
- 检查现有Debian安装
- 提供自定义安装路径选项
- 安装Debian系统
- 配置WSL环境
#### 使用方法
```batch
# 使用批处理脚本
install-debian.bat
# 使用PowerShell脚本
.\install-debian.ps1
```
### run-check-wsl-ps.bat
运行WSL检查脚本的批处理文件。
#### 功能
- 以管理员权限运行PowerShell脚本
- 处理脚本执行结果
#### 使用方法
```batch
run-check-wsl-ps.bat
```
### run-install-debian-ps.bat
运行Debian安装脚本的批处理文件。
#### 功能
- 以管理员权限运行PowerShell脚本
- 处理脚本执行结果
#### 使用方法
```batch
run-install-debian-ps.bat
```
## 依赖要求
- Windows 10/11
- 管理员权限
- PowerShell 5.1或更高版本
- 网络连接(用于下载和安装)
## 使用顺序
1. 首先运行 `check-wsl.bat``check-wsl.ps1` 检查环境
2. 如果环境检查通过,运行 `install-debian.bat``install-debian.ps1` 安装Debian
3. 安装完成后重启WSL或计算机
## 注意事项
- 所有脚本需要管理员权限运行
- 安装过程中需要网络连接
- 建议在安装前备份重要数据
- 如果遇到问题检查Windows更新和WSL功能是否启用
## 常见问题
1. 如果脚本无法运行,确保以管理员身份运行
2. 如果WSL2未启用按照提示启用WSL2
3. 如果安装失败,检查网络连接和系统要求
4. 如果遇到权限问题,确保使用管理员权限运行
## 更新日志
### v1.0.0 (2024-03-xx)
- 初始版本发布
- 完成WSL环境检查功能
- 实现Debian安装功能
- 添加批处理和PowerShell脚本支持

View File

@ -12,82 +12,84 @@ if %errorlevel% neq 0 (
)
echo.
echo [INFO] 开始检查 WSL2 环境...
echo INFO: 开始检查 WSL2 环境...
echo.
:: Check Windows version
echo [INFO] 检查 Windows 版本...
echo INFO: 检查 Windows 版本...
for /f "tokens=*" %%a in ('ver') do set "windows_version=%%a"
echo Windows 版本: !windows_version!
:: Check WSL installation
echo [INFO] 检查 WSL 安装状态...
echo INFO: 检查 WSL 安装状态...
wsl --version >nul 2>&1
if %errorlevel% equ 0 (
echo [INFO] WSL 已安装
echo INFO: WSL 已安装
echo.
wsl --version
echo.
) else (
echo [ERROR] WSL 未安装
echo [INFO] 请访问 https://aka.ms/wsl 安装 WSL
echo ERROR: WSL 未安装
echo INFO: 请访问 https://aka.ms/wsl 安装 WSL
goto :error
)
:: Check WSL2 status
echo [INFO] 检查 WSL2 状态...
echo INFO: 检查 WSL2 状态...
wsl -l -v > temp.txt
findstr /i "2" temp.txt >nul
if %errorlevel% equ 0 (
echo [INFO] WSL2 已启用
echo [INFO] WSL 发行版列表:
type temp.txt
echo INFO: WSL2 已启用
) else (
echo [WARN] WSL2 未启用
echo [INFO] 请运行以下命令启用 WSL2:
echo WARN: WSL2 未启用
echo INFO: WSL 发行版列表:
echo.
wsl -l -v
echo.
echo INFO: 请运行以下命令启用 WSL2:
echo wsl --set-default-version 2
goto :error
)
del temp.txt
:: Check Debian installation
echo [INFO] 检查 Debian 安装状态...
echo INFO: 检查 Debian 安装状态...
wsl -d Debian echo "Debian is installed" >nul 2>&1
if %errorlevel% equ 0 (
echo [INFO] Debian 已安装
echo INFO: Debian 已安装
) else (
echo [WARN] Debian 未安装
echo [INFO] 请运行以下命令安装 Debian:
echo WARN: Debian 未安装
echo INFO: 请运行以下命令安装 Debian:
echo wsl --install -d Debian
goto :error
)
:: Check virtualization
echo [INFO] 检查虚拟化状态...
echo INFO: 检查虚拟化状态...
systeminfo | findstr /i "Hyper-V" > temp.txt
findstr /i "Virtual Ethernet Adapter" temp.txt >nul
if %errorlevel% equ 0 (
echo [INFO] 虚拟化已启用
echo INFO: 虚拟化已启用
) else (
findstr /i "hypervisor has been detected" temp.txt >nul
if %errorlevel% equ 0 (
echo [INFO] 虚拟化已启用
echo INFO: 虚拟化已启用
) else (
echo [ERROR] 虚拟化未启用
echo [INFO] 请在 BIOS 中启用虚拟化 (Intel VT-x 或 AMD-V)
echo ERROR: 虚拟化未启用
echo INFO: 请在 BIOS 中启用虚拟化 (Intel VT-x 或 AMD-V)
goto :error
)
)
del temp.txt
:: Check Windows features
echo [INFO] 检查 Windows 功能...
echo INFO: 检查 Windows 功能...
dism /online /get-featureinfo /featurename:Microsoft-Windows-Subsystem-Linux > temp.txt
findstr /i "状态.*已启用" temp.txt >nul
if %errorlevel% equ 0 (
echo [INFO] Linux 子系统已启用
echo INFO: Linux 子系统已启用
) else (
echo [WARN] Linux 子系统未启用
echo [INFO] 请运行以下命令启用 Linux 子系统:
echo WARN: Linux 子系统未启用
echo INFO: 请运行以下命令启用 Linux 子系统:
echo dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
goto :error
)
@ -95,10 +97,10 @@ if %errorlevel% equ 0 (
dism /online /get-featureinfo /featurename:VirtualMachinePlatform > temp.txt
findstr /i "状态.*已启用" temp.txt >nul
if %errorlevel% equ 0 (
echo [INFO] 虚拟机平台已启用
echo INFO: 虚拟机平台已启用
) else (
echo [WARN] 虚拟机平台未启用
echo [INFO] 请运行以下命令启用虚拟机平台:
echo WARN: 虚拟机平台未启用
echo INFO: 请运行以下命令启用虚拟机平台:
echo dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
goto :error
)
@ -109,24 +111,25 @@ echo ============================================
echo 检查完成!环境已就绪
echo ============================================
echo.
echo [INFO] 您的 WSL2 环境已经准备就绪:
echo [INFO] 1. Windows 版本符合要求
echo [INFO] 2. WSL2 已正确安装并启用
echo [INFO] 3. Debian 发行版已安装
echo [INFO] 4. 虚拟化功能已启用
echo [INFO] 5. 所需的 Windows 功能已启用
echo INFO: 您的 WSL2 环境已经准备就绪:
echo.
echo [INFO] 您现在可以开始使用 WSL2 环境了!
echo INFO: 1. Windows 版本符合要求
echo INFO: 2. WSL2 已正确安装并启用
echo INFO: 3. Debian 发行版已安装
echo INFO: 4. 虚拟化功能已启用
echo INFO: 5. 所需的 Windows 功能已启用
echo.
echo INFO: 您现在可以开始使用 WSL2 环境了!
echo ============================================
echo.
echo [INFO] 按任意键退出...
echo INFO: 按任意键退出...
pause >nul
goto :eof
:error
echo.
echo [WARN] 检查未通过,请按照提示解决问题
echo [INFO] 按任意键退出...
echo WARN: 检查未通过,请按照提示解决问题
echo INFO: 按任意键退出...
pause >nul
exit /b 1

View File

@ -0,0 +1,187 @@
# WSL2 Environment Check Script
# This script checks WSL2 installation status on Windows
# Set error action
$ErrorActionPreference = 'Stop'
# Color definitions
$Red = [System.ConsoleColor]::Red
$Green = [System.ConsoleColor]::Green
$Yellow = [System.ConsoleColor]::Yellow
# Logging functions
function Write-Info {
param([string]$Message)
Write-Host '[INFO] ' -NoNewline -ForegroundColor $Green
Write-Host $Message
}
function Write-Warn {
param([string]$Message)
Write-Host '[WARN] ' -NoNewline -ForegroundColor $Yellow
Write-Host $Message
}
function Write-Error {
param([string]$Message)
Write-Host '[ERROR] ' -NoNewline -ForegroundColor $Red
Write-Host $Message
}
function Wait-KeyPress {
Write-Host "`nPress any key to exit..." -NoNewline
$null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown')
Write-Host ''
}
# Check administrator privileges
if (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
Write-Warn 'Administrator privileges required'
Write-Info 'Please right-click this script and select "Run as Administrator"'
Wait-KeyPress
exit 1
}
Write-Info "`nStarting WSL2 environment check...`n"
# Check Windows version
Write-Info 'Checking Windows version...'
$windowsVersion = (Get-WmiObject Win32_OperatingSystem).Caption
Write-Host "Windows Version: $windowsVersion"
# Check WSL installation status
Write-Info 'Checking WSL installation...'
try {
$wslVersion = wsl --version
Write-Info 'WSL is installed'
Write-Host "`n$wslVersion`n"
} catch {
Write-Error 'WSL is not installed'
Write-Info 'Please visit https://aka.ms/wsl to install WSL'
Wait-KeyPress
exit 1
} finally {
# Clear errors
$error.clear()
}
# Check WSL2 status
Write-Info 'Checking WSL2 status...'
try {
$wslList = wsl -l -v
if ($wslList -match '2') {
Write-Info 'WSL2 is enabled'
} else {
Write-Warn 'WSL2 is not enabled'
Write-Info 'WSL distribution list:'
Write-Host "`n$wslList`n"
Write-Info 'Please run the following command to enable WSL2:'
Write-Host 'wsl --set-default-version 2'
Wait-KeyPress
exit 1
}
} catch {
Write-Error "Failed to get WSL status: $($_.Exception.Message)"
Wait-KeyPress
exit 1
} finally {
# Clear errors
$error.clear()
}
# Check Debian installation status
Write-Info 'Checking Debian installation...'
try {
wsl -d Debian echo 'Debian is installed' | Out-Null
Write-Info 'Debian is installed'
} catch {
Write-Warn 'Debian is not installed'
Write-Info 'Please run the following command to install Debian:'
Write-Host 'wsl --install -d Debian'
Wait-KeyPress
exit 1
} finally {
# Clear errors
$error.clear()
}
# Check virtualization status
Write-Info 'Checking virtualization status...'
try {
$systemInfo = systeminfo
if ($systemInfo -match 'Virtual Ethernet Adapter' -or $systemInfo -match 'hypervisor has been detected') {
Write-Info 'Virtualization is enabled'
} else {
Write-Error 'Virtualization is not enabled'
Write-Info 'Please enable virtualization (Intel VT-x or AMD-V) in BIOS'
Wait-KeyPress
exit 1
}
} catch {
Write-Error "Failed to check virtualization status: $($_.Exception.Message)"
Wait-KeyPress
exit 1
} finally {
# Clear errors
$error.clear()
}
# Check Windows features
Write-Info 'Checking Windows features...'
# Check Linux subsystem
try {
$wslFeature = Get-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux
if ($wslFeature.State -eq 'Enabled') {
Write-Info 'Linux subsystem is enabled'
} else {
Write-Warn 'Linux subsystem is not enabled'
Write-Info 'Please run the following command to enable Linux subsystem:'
Write-Host 'dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart'
Wait-KeyPress
exit 1
}
} catch {
Write-Error "Failed to check Linux subsystem status: $($_.Exception.Message)"
Wait-KeyPress
exit 1
} finally {
# Clear errors
$error.clear()
}
# Check virtual machine platform
try {
$vmPlatform = Get-WindowsOptionalFeature -Online -FeatureName VirtualMachinePlatform
if ($vmPlatform.State -eq 'Enabled') {
Write-Info 'Virtual Machine Platform is enabled'
} else {
Write-Warn 'Virtual Machine Platform is not enabled'
Write-Info 'Please run the following command to enable Virtual Machine Platform:'
Write-Host 'dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart'
Wait-KeyPress
exit 1
}
} catch {
Write-Error "Failed to check Virtual Machine Platform status: $($_.Exception.Message)"
Wait-KeyPress
exit 1
} finally {
# Clear errors
$error.clear()
}
Write-Host "`n============================================"
Write-Host " Check Complete! "
Write-Host "============================================"
Write-Host "`nYour WSL2 environment is ready:`n"
Write-Info '1. Windows version is compatible'
Write-Info '2. WSL2 is installed and enabled'
Write-Info '3. Debian distribution is installed'
Write-Info '4. Virtualization is enabled'
Write-Info '5. Required Windows features are enabled'
Write-Info 'You can now start using WSL2!'
Write-Host "============================================"
# Wait for user input before exit
Wait-KeyPress

View File

@ -1,192 +0,0 @@
# WSL2 环境检查脚本
# 此脚本用于检查 Windows 系统上的 WSL2 安装状态
# 设置错误操作
$ErrorActionPreference = "Stop"
# 颜色定义
$Red = [System.ConsoleColor]::Red
$Green = [System.ConsoleColor]::Green
$Yellow = [System.ConsoleColor]::Yellow
# 日志函数
function Write-Info {
param([string]$Message)
Write-Host "[INFO] $Message" -ForegroundColor $Green
}
function Write-Warn {
param([string]$Message)
Write-Host "[WARN] $Message" -ForegroundColor $Yellow
}
function Write-Error {
param([string]$Message)
Write-Host "[ERROR] $Message" -ForegroundColor $Red
}
# 检查 Windows 版本
function Test-WindowsVersion {
Write-Info "检查 Windows 版本..."
$os = Get-WmiObject -Class Win32_OperatingSystem
$version = [System.Environment]::OSVersion.Version
Write-Info "Windows 版本: $($os.Caption)"
Write-Info "系统版本号: $($version.Major).$($version.Minor).$($version.Build)"
if ($version.Major -lt 10 -or ($version.Major -eq 10 -and $version.Build -lt 19041)) {
Write-Error "Windows 版本不满足 WSL2 要求,需要 Windows 10 版本 2004 或更高版本"
return $false
}
return $true
}
# 检查 WSL 是否安装
function Test-WSLInstallation {
Write-Info "检查 WSL 安装状态..."
try {
$wslVersion = wsl --version 2>$null
if ($LASTEXITCODE -eq 0) {
Write-Info "WSL 已安装"
Write-Info "WSL 版本信息:"
Write-Host $wslVersion
return $true
}
}
catch {
Write-Error "WSL 未安装"
Write-Info "请访问 https://aka.ms/wsl 安装 WSL"
return $false
}
}
# 检查 WSL2 是否启用
function Test-WSL2Enabled {
Write-Info "检查 WSL2 状态..."
try {
$wslList = wsl -l -v
if ($wslList -match "VERSION.*2") {
Write-Info "WSL2 已启用"
Write-Info "WSL 发行版列表:"
Write-Host $wslList
return $true
}
else {
Write-Warn "WSL2 未启用"
Write-Info "请运行以下命令启用 WSL2"
Write-Host "wsl --set-default-version 2"
return $false
}
}
catch {
Write-Error "获取 WSL 版本信息失败"
return $false
}
}
# 检查虚拟化是否启用
function Test-VirtualizationEnabled {
Write-Info "检查虚拟化状态..."
try {
$vmx = Get-WmiObject -Class Win32_Processor | Select-Object -ExpandProperty NumberOfLogicalProcessors
if ($vmx -gt 0) {
Write-Info "虚拟化已启用"
return $true
}
else {
Write-Error "虚拟化未启用"
Write-Info "请在 BIOS 中启用虚拟化技术Intel VT-x 或 AMD-V"
return $false
}
}
catch {
Write-Error "检查虚拟化状态失败"
return $false
}
}
# 检查 Debian 是否安装
function Test-DebianInstallation {
Write-Info "检查 Debian 安装状态..."
try {
$wslList = wsl -l
if ($wslList -match "Debian") {
Write-Info "Debian 已安装"
return $true
}
else {
Write-Warn "Debian 未安装"
Write-Info "请运行以下命令安装 Debian"
Write-Host "wsl --install -d Debian"
return $false
}
}
catch {
Write-Error "检查 Debian 安装状态失败"
return $false
}
}
# 检查 Windows 功能
function Test-WindowsFeatures {
Write-Info "检查 Windows 功能..."
$features = @(
"Microsoft-Windows-Subsystem-Linux",
"VirtualMachinePlatform"
)
$allEnabled = $true
foreach ($feature in $features) {
$status = Get-WindowsOptionalFeature -Online -FeatureName $feature
if ($status.State -eq "Enabled") {
Write-Info "$feature 已启用"
}
else {
Write-Warn "$feature 未启用"
Write-Info "请运行以下命令启用 $feature"
Write-Host "dism.exe /online /enable-feature /featurename:$feature /all /norestart"
$allEnabled = $false
}
}
return $allEnabled
}
# 主函数
function Main {
Write-Info "开始检查 WSL2 环境..."
$checks = @{
"Windows 版本检查" = { Test-WindowsVersion }
"WSL 安装检查" = { Test-WSLInstallation }
"WSL2 状态检查" = { Test-WSL2Enabled }
"虚拟化检查" = { Test-VirtualizationEnabled }
"Debian 安装检查" = { Test-DebianInstallation }
"Windows 功能检查" = { Test-WindowsFeatures }
}
$allPassed = $true
foreach ($check in $checks.GetEnumerator()) {
Write-Host "`n=== $($check.Key) ==="
if (-not (& $check.Value)) {
$allPassed = $false
}
}
if ($allPassed) {
Write-Info "`n所有检查项通过WSL2 环境已准备就绪。"
}
else {
Write-Warn "`n部分检查项未通过,请按照提示进行修复。"
}
}
# 执行主函数
Main

View File

@ -0,0 +1,181 @@
@echo off
setlocal enabledelayedexpansion
:: Set console colors
set "GREEN=[32m"
set "YELLOW=[33m"
set "RED=[31m"
set "RESET=[0m"
:: Function to print colored messages
call :define_print_functions
echo %GREEN%[INFO]%RESET% Starting WSL2 environment configuration...
echo.
:: Check for Administrator privileges
net session >nul 2>&1
if %errorLevel% neq 0 (
echo %YELLOW%[WARN]%RESET% Administrator privileges required
echo %GREEN%[INFO]%RESET% Please run this script as Administrator
pause
exit /b 1
)
echo %GREEN%[INFO]%RESET% Note: Please make sure you have manually updated WSL2 kernel before proceeding.
echo %GREEN%[INFO]%RESET% You can update WSL2 kernel by running "wsl --update" in an administrator PowerShell.
echo.
:: Check if Debian is installed
echo %GREEN%[INFO]%RESET% Checking Debian installation...
wsl -d Debian echo "Check Debian" >nul 2>&1
if %ERRORLEVEL% equ 0 (
echo %GREEN%[INFO]%RESET% Found existing Debian installation
:: Ask if user wants to remove existing installation
set /p "remove=Do you want to remove the existing Debian installation? [y/N] "
if /i "!remove!"=="y" (
echo %GREEN%[INFO]%RESET% Removing existing Debian installation...
wsl --unregister Debian
if !ERRORLEVEL! neq 0 (
echo %RED%[ERROR]%RESET% Failed to remove Debian
pause
exit /b 1
)
echo %GREEN%[INFO]%RESET% Existing Debian installation removed
set "NEED_INSTALL=1"
)
) else (
echo %GREEN%[INFO]%RESET% No existing Debian installation found
set "NEED_INSTALL=1"
)
:: Handle Debian installation if needed
if defined NEED_INSTALL (
:: Get custom installation path
set "DEFAULT_PATH=%USERPROFILE%\WSL\Debian"
echo.
echo Current WSL installation path: %DEFAULT_PATH%
set /p "CUSTOM_PATH=Enter new installation path or press Enter to keep current: "
if not "!CUSTOM_PATH!"=="" (
echo %GREEN%[INFO]%RESET% Setting up custom installation path: !CUSTOM_PATH!
:: Create directory if it doesn't exist
if not exist "!CUSTOM_PATH!" (
mkdir "!CUSTOM_PATH!" 2>nul
if !ERRORLEVEL! neq 0 (
echo %RED%[ERROR]%RESET% Failed to create directory: !CUSTOM_PATH!
pause
exit /b 1
)
echo %GREEN%[INFO]%RESET% Created directory: !CUSTOM_PATH!
)
:: Set WSL installation path
echo %GREEN%[INFO]%RESET% Setting WSL installation path...
setx WSLENV "WSLPATH/up:!CUSTOM_PATH!" >nul
if !ERRORLEVEL! neq 0 (
echo %RED%[ERROR]%RESET% Failed to set WSL installation path
pause
exit /b 1
)
echo %GREEN%[INFO]%RESET% WSL installation path set to: !CUSTOM_PATH!
)
:: Install Debian
echo %GREEN%[INFO]%RESET% Installing Debian...
wsl --install -d Debian
if !ERRORLEVEL! neq 0 (
echo %RED%[ERROR]%RESET% Failed to install Debian
pause
exit /b 1
)
echo %GREEN%[INFO]%RESET% Debian installation completed
:: Wait for Debian to be ready
echo %GREEN%[INFO]%RESET% Waiting for Debian to be ready...
timeout /t 10 /nobreak >nul
)
:: Shutdown WSL to ensure clean state
echo %GREEN%[INFO]%RESET% Shutting down WSL to ensure clean state...
wsl --shutdown
if %ERRORLEVEL% neq 0 (
echo %RED%[ERROR]%RESET% Failed to shutdown WSL
pause
exit /b 1
)
timeout /t 2 /nobreak >nul
echo %GREEN%[INFO]%RESET% WSL shutdown completed
:: Update Debian system
echo %GREEN%[INFO]%RESET% Updating Debian system packages...
echo %GREEN%[INFO]%RESET% Updating package lists...
wsl -d Debian -u root apt update
if %ERRORLEVEL% neq 0 (
echo %RED%[ERROR]%RESET% Failed to update package lists
pause
exit /b 1
)
echo %GREEN%[INFO]%RESET% Upgrading packages...
wsl -d Debian -u root apt upgrade -y
if %ERRORLEVEL% neq 0 (
echo %RED%[ERROR]%RESET% Failed to upgrade packages
pause
exit /b 1
)
echo %GREEN%[INFO]%RESET% Cleaning up...
wsl -d Debian -u root apt autoremove -y
wsl -d Debian -u root apt clean
echo %GREEN%[INFO]%RESET% Debian system update completed
:: Configure WSL memory limit
echo %GREEN%[INFO]%RESET% Configuring WSL memory limit...
set "CONFIG_FILE=%USERPROFILE%\.wslconfig"
:: Backup existing config if it exists
if exist "%CONFIG_FILE%" (
echo %GREEN%[INFO]%RESET% Backing up existing .wslconfig...
copy "%CONFIG_FILE%" "%CONFIG_FILE%.bak" >nul
)
:: Create new config file
(
echo [wsl2]
echo memory=8GB
echo processors=4
echo swap=2GB
) > "%CONFIG_FILE%"
if %ERRORLEVEL% neq 0 (
echo %RED%[ERROR]%RESET% Failed to create .wslconfig
pause
exit /b 1
)
echo %GREEN%[INFO]%RESET% WSL memory limit configured
echo.
echo ============================================
echo Configuration Complete!
echo ============================================
echo.
echo Your WSL2 environment has been configured:
echo.
echo %GREEN%[INFO]%RESET% 1. Debian system packages updated
echo %GREEN%[INFO]%RESET% 2. WSL memory limit configured (8GB RAM, 4 cores, 2GB swap)
if defined CUSTOM_PATH (
echo %GREEN%[INFO]%RESET% 3. WSL installation path set to: !CUSTOM_PATH!
)
echo %GREEN%[INFO]%RESET% Please restart your computer to apply all changes.
echo ============================================
pause
exit /b 0
:define_print_functions
exit /b 0

View File

@ -0,0 +1,213 @@
# WSL2 Environment Upgrade Script
# This script upgrades Debian system packages and configures WSL2 settings
# Set error action
$ErrorActionPreference = 'Stop'
# Color definitions
$Red = [System.ConsoleColor]::Red
$Green = [System.ConsoleColor]::Green
$Yellow = [System.ConsoleColor]::Yellow
# Logging functions
function Write-Info {
param([string]$Message)
Write-Host '[INFO] ' -NoNewline -ForegroundColor $Green
Write-Host $Message
}
function Write-Warn {
param([string]$Message)
Write-Host '[WARN] ' -NoNewline -ForegroundColor $Yellow
Write-Host $Message
}
function Write-Error {
param([string]$Message)
Write-Host '[ERROR] ' -NoNewline -ForegroundColor $Red
Write-Host $Message
}
function Wait-KeyPress {
Write-Host "`nPress any key to exit..." -NoNewline
$null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown')
Write-Host ''
}
function Get-UserConfirmation {
param([string]$Message)
$response = Read-Host -Prompt "$Message [y/N]"
return $response -eq 'y' -or $response -eq 'Y'
}
function Get-CustomPath {
param([string]$DefaultPath)
Write-Host "`nCurrent WSL installation path: $DefaultPath"
$response = Read-Host -Prompt "Enter new installation path or press Enter to keep current"
if ([string]::IsNullOrWhiteSpace($response)) {
return $DefaultPath
}
return $response
}
# Check administrator privileges
if (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
Write-Warn 'Administrator privileges required'
Write-Info 'Please run this script as Administrator'
Wait-KeyPress
exit 1
}
Write-Info "`nStarting WSL2 environment configuration...`n"
Write-Info 'Note: Please make sure you have manually updated WSL2 kernel before proceeding.'
Write-Info 'You can update WSL2 kernel by running "wsl --update" in an administrator PowerShell.'
Write-Host ''
# Check if Debian is installed
$debianInstalled = $false
try {
wsl -d Debian echo "Check Debian" 2>$null
$debianInstalled = $true
Write-Info "Found existing Debian installation"
} catch {
Write-Info "No existing Debian installation found"
}
# Handle existing Debian installation
if ($debianInstalled) {
if (Get-UserConfirmation "Do you want to remove the existing Debian installation?") {
Write-Info "Removing existing Debian installation..."
try {
wsl --unregister Debian
Write-Info "Existing Debian installation removed"
$debianInstalled = $false
} catch {
Write-Error "Failed to remove Debian: $($_.Exception.Message)"
Wait-KeyPress
exit 1
}
}
}
# Get custom installation path if Debian needs to be installed
if (-not $debianInstalled) {
$defaultPath = "$env:USERPROFILE\WSL\Debian"
$customPath = Get-CustomPath $defaultPath
if ($customPath -ne $defaultPath) {
Write-Info "Setting up custom installation path: $customPath"
# Create directory if it doesn't exist
if (-not (Test-Path $customPath)) {
try {
New-Item -ItemType Directory -Path $customPath -Force | Out-Null
Write-Info "Created directory: $customPath"
} catch {
Write-Error "Failed to create directory: $($_.Exception.Message)"
Wait-KeyPress
exit 1
}
}
# Set WSL default installation path
Write-Info "Setting WSL installation path..."
try {
[System.Environment]::SetEnvironmentVariable('WSLENV', "WSLPATH/up:$customPath", [System.EnvironmentVariableTarget]::User)
Write-Info "WSL installation path set to: $customPath"
} catch {
Write-Error "Failed to set WSL installation path: $($_.Exception.Message)"
Wait-KeyPress
exit 1
}
}
# Install Debian
Write-Info "Installing Debian..."
try {
wsl --install -d Debian
Write-Info "Debian installation completed"
# Wait for Debian to be ready
Write-Info "Waiting for Debian to be ready..."
Start-Sleep -Seconds 10
} catch {
Write-Error "Failed to install Debian: $($_.Exception.Message)"
Wait-KeyPress
exit 1
}
}
# Shutdown WSL to ensure clean state
Write-Info 'Shutting down WSL to ensure clean state...'
try {
wsl --shutdown
Start-Sleep -Seconds 2
Write-Info 'WSL shutdown completed'
} catch {
Write-Error "Failed to shutdown WSL: $($_.Exception.Message)"
Wait-KeyPress
exit 1
}
# Update Debian system
Write-Info 'Updating Debian system packages...'
try {
# Update package lists
Write-Info 'Updating package lists...'
wsl -d Debian -u root apt update
# Upgrade packages
Write-Info 'Upgrading packages...'
wsl -d Debian -u root apt upgrade -y
# Clean up
Write-Info 'Cleaning up...'
wsl -d Debian -u root apt autoremove -y
wsl -d Debian -u root apt clean
Write-Info 'Debian system update completed'
} catch {
Write-Error "Failed to update Debian system: $($_.Exception.Message)"
Wait-KeyPress
exit 1
}
# Configure WSL memory limit
Write-Info 'Configuring WSL memory limit...'
try {
$wslConfigPath = "$env:USERPROFILE\.wslconfig"
$wslConfig = @"
[wsl2]
memory=8GB
processors=4
swap=2GB
"@
if (Test-Path $wslConfigPath) {
Write-Info 'Backing up existing .wslconfig...'
Copy-Item $wslConfigPath "$wslConfigPath.bak"
}
$wslConfig | Out-File $wslConfigPath -Encoding UTF8
Write-Info 'WSL memory limit configured'
} catch {
Write-Error "Failed to configure WSL memory limit: $($_.Exception.Message)"
Wait-KeyPress
exit 1
}
Write-Host "`n============================================"
Write-Host " Configuration Complete! "
Write-Host "============================================"
Write-Host "`nYour WSL2 environment has been configured:`n"
Write-Info '1. Debian system packages updated'
Write-Info '2. WSL memory limit configured (8GB RAM, 4 cores, 2GB swap)'
if (-not [string]::IsNullOrWhiteSpace($customPath)) {
Write-Info "3. WSL installation path set to: $customPath"
}
Write-Info 'Please restart your computer to apply all changes.'
Write-Host "============================================"
# Wait for user input before exit
Wait-KeyPress

View File

@ -0,0 +1,3 @@
@echo off
cd /d "%~dp0"
PowerShell -NoProfile -ExecutionPolicy Bypass -Command "Start-Process PowerShell -ArgumentList '-NoProfile -ExecutionPolicy Bypass -File \"%~dp0check-wsl.ps1\"' -Verb RunAs"

View File

@ -0,0 +1,3 @@
@echo off
cd /d "%~dp0"
PowerShell -NoProfile -ExecutionPolicy Bypass -Command "Start-Process PowerShell -ArgumentList '-NoProfile -ExecutionPolicy Bypass -File \"%~dp0install-debian.ps1\"' -Verb RunAs"

Binary file not shown.

View File

@ -1,129 +0,0 @@
@echo off
chcp 65001 >nul
setlocal enabledelayedexpansion
:: Check for admin privileges
net session >nul 2>&1
if %errorlevel% neq 0 (
echo "[WARN] 需要管理员权限"
echo "[INFO] 请右键点击此脚本,选择"以管理员身份运行""
pause
exit /b 1
)
echo.
echo "[INFO] 开始升级 WSL2 并重新安装 Debian..."
echo.
:: Check WSL installation
echo "[INFO] 检查 WSL 安装状态..."
wsl --version >nul 2>&1
if %errorlevel% neq 0 (
echo "[ERROR] WSL 未安装"
echo "[INFO] 请访问 https://aka.ms/wsl 安装 WSL"
goto :error
)
:: Upgrade WSL
echo "[INFO] 正在升级 WSL..."
wsl --update
if %errorlevel% neq 0 (
echo "[ERROR] WSL 升级失败"
goto :error
)
echo "[INFO] WSL 升级完成"
:: Set WSL2 as default
echo "[INFO] 设置 WSL2 为默认版本..."
wsl --set-default-version 2
if %errorlevel% neq 0 (
echo "[ERROR] 设置 WSL2 为默认版本失败"
goto :error
)
echo "[INFO] WSL2 已设置为默认版本"
:: Check if Debian is installed
echo "[INFO] 检查 Debian 安装状态..."
wsl -d Debian echo "Debian is installed" >nul 2>&1
if %errorlevel% equ 0 (
echo "[INFO] 检测到已安装的 Debian"
echo.
echo "[WARN] 是否要卸载现有的 Debian"
echo "[INFO] 1. 是"
echo "[INFO] 2. 否"
echo.
set /p "choice=请选择 (1/2): "
if "!choice!"=="1" (
echo "[INFO] 正在卸载 Debian..."
wsl --unregister Debian
if %errorlevel% neq 0 (
echo "[ERROR] Debian 卸载失败"
goto :error
)
echo "[INFO] Debian 已卸载"
) else (
echo "[INFO] 已取消卸载 Debian"
goto :error
)
)
:: Choose installation location
echo.
echo "[INFO] 请选择 Debian 安装位置:"
echo "[INFO] 1. 默认位置"
echo "[INFO] 2. 自定义位置"
echo.
set /p "location=请选择 (1/2): "
if "!location!"=="2" (
echo "[INFO] 请输入安装路径例如D:\WSL\Debian"
set /p "install_path=安装路径: "
if not exist "!install_path!" mkdir "!install_path!"
echo "[INFO] 正在安装 Debian 到 !install_path! ..."
wsl --install -d Debian --location "!install_path!"
) else (
echo "[INFO] 正在安装 Debian 到默认位置..."
wsl --install -d Debian
)
if %errorlevel% neq 0 (
echo "[ERROR] Debian 安装失败"
goto :error
)
echo "[INFO] Debian 安装完成"
:: Verify installation
echo "[INFO] 验证安装..."
wsl -d Debian echo "Debian is installed" >nul 2>&1
if %errorlevel% equ 0 (
echo "[INFO] Debian 安装验证成功"
echo "[INFO] 请打开新的终端窗口,完成 Debian 的初始设置"
) else (
echo "[ERROR] Debian 安装验证失败"
goto :error
)
echo.
echo "============================================"
echo " 升级和安装完成!"
echo "============================================"
echo.
echo "[INFO] 请按照以下步骤完成设置:"
echo "[INFO] 1. 打开新的终端窗口"
echo "[INFO] 2. 等待 Debian 首次启动"
echo "[INFO] 3. 设置用户名和密码"
echo "[INFO] 4. 运行 check_windows_wsl.bat 验证环境"
echo.
echo "[INFO] 按任意键退出..."
pause >nul
goto :eof
:error
echo.
echo "[WARN] 操作失败,请检查错误信息"
echo "[INFO] 按任意键退出..."
pause >nul
exit /b 1
:eof
endlocal

115
scripts/utils/README.md Normal file
View File

@ -0,0 +1,115 @@
# 工具脚本集合
本目录包含各种通用工具脚本,用于提供基础功能和辅助其他脚本运行。
## 目录结构
```
utils/
├── README.md # 本文档
├── common.sh # 通用shell函数库
└── check_user.sh # 用户权限检查工具
```
## 脚本说明
### common.sh
通用shell函数库提供了各种常用的shell函数。
#### 功能
- 日志管理
- `setup_logging`: 设置日志系统
- `log_info`: 记录信息日志
- `log_warn`: 记录警告日志
- `log_error`: 记录错误日志
- `log_success`: 记录成功日志
- 进度显示
- `show_progress`: 显示进度条
- `update_progress`: 更新进度
- 网络管理
- `check_network`: 检查网络连接
- `get_mirror_url`: 获取镜像源URL
- 配置管理
- `manage_config`: 管理配置文件
- `manage_plugin`: 管理插件
- 依赖管理
- `check_dependencies`: 检查依赖
- `install_base_dependencies`: 安装基础依赖
- 用户交互
- `confirm`: 用户确认提示
- `get_user_info`: 获取用户信息
- 文件管理
- `download_file`: 下载文件
- `manage_path`: 管理PATH环境变量
- `manage_alias`: 管理命令别名
#### 使用方法
```bash
# 在脚本中引入
source ./utils/common.sh
# 使用函数
log_info "开始安装..."
show_progress "安装进度" 0
```
### check_user.sh
用户权限检查工具,用于检查脚本运行环境和权限。
#### 功能
- 检查root权限
- 检查用户信息
- 检查系统环境
- 检查必要命令
#### 使用方法
```bash
# 在脚本中引入
source ./utils/check_user.sh
# 检查权限
check_root
```
## 依赖要求
- Debian/Ubuntu系统
- bash shell
- 基本系统工具curl, wget等
## 使用建议
1. 在脚本开头引入需要的工具脚本
2. 使用提供的函数而不是直接实现功能
3. 遵循错误处理和日志记录规范
4. 使用进度显示提供更好的用户体验
## 注意事项
- 确保脚本有执行权限
- 注意函数的依赖关系
- 正确处理错误情况
- 保持日志记录的完整性
## 常见问题
1. 如果函数未定义,检查是否正确引入了脚本
2. 如果权限检查失败确保使用sudo运行
3. 如果网络检查失败,检查网络连接
4. 如果日志记录失败,检查日志目录权限
## 更新日志
### v1.0.0 (2024-03-xx)
- 初始版本发布
- 完成通用函数库
- 实现用户检查工具
- 添加完整的错误处理

View File

@ -0,0 +1,40 @@
#!/bin/bash
# 导入公共函数
source "$(dirname "$0")/common.sh"
# 检查root权限
check_root
# 获取用户信息
get_user_info
# 显示用户信息
echo "当前环境信息:"
echo "-----------------------------"
echo "EUID: $EUID"
echo "USER: $USER"
echo "SUDO_USER: $SUDO_USER"
echo "CURRENT_USER: $CURRENT_USER"
echo "USER_HOME: $USER_HOME"
echo "-----------------------------"
echo "用户和组信息:"
echo "-----------------------------"
id "$CURRENT_USER"
echo "-----------------------------"
echo "用户主目录内容:"
echo "-----------------------------"
ls -la "$USER_HOME"
echo "-----------------------------"
echo "Shell信息"
echo "-----------------------------"
echo "当前Shell: $SHELL"
echo "默认Shell: $(getent passwd "$CURRENT_USER" | cut -d: -f7)"
echo "-----------------------------"
echo "用户组信息:"
echo "-----------------------------"
groups "$CURRENT_USER"
echo "-----------------------------"
echo "sudo权限检查"
echo "-----------------------------"
sudo -l -U "$CURRENT_USER"

463
scripts/utils/common.sh Normal file
View File

@ -0,0 +1,463 @@
#!/bin/bash
# 设置严格模式
set -euo pipefail
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# 初始化日志
setup_logging() {
local log_dir="${USER_HOME}/.logs"
local log_file="${log_dir}/shell_setup_$(date +%Y%m%d_%H%M%S).log"
mkdir -p "$log_dir"
exec 1> >(tee -a "$log_file")
exec 2> >(tee -a "$log_file" >&2)
log_info "开始记录日志到: $log_file"
}
# 日志函数
log_info() {
echo -e "${GREEN}[INFO]${NC} $1" | tee -a "${LOG_FILE:-/dev/null}"
}
log_warn() {
echo -e "${YELLOW}[WARN]${NC} $1" | tee -a "${LOG_FILE:-/dev/null}"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1" | tee -a "${LOG_FILE:-/dev/null}"
}
log_success() {
echo -e "${BLUE}[SUCCESS]${NC} $1" | tee -a "${LOG_FILE:-/dev/null}"
}
# 进度显示函数
show_progress() {
local msg="$1"
echo -ne "\r${GREEN}[INFO]${NC} $msg... "
}
update_progress() {
local msg="$1"
local status="$2"
echo -e "\r${GREEN}[INFO]${NC} $msg... ${status}"
}
# 清理函数
cleanup() {
local exit_code=$?
if [ $exit_code -ne 0 ]; then
log_error "脚本执行失败,退出码: $exit_code"
if [ -n "${LAST_BACKUP:-}" ] && [ -f "$LAST_BACKUP" ]; then
log_info "正在恢复配置文件..."
manage_config "restore" "$LAST_BACKUP"
fi
fi
exit $exit_code
}
# 网络检查函数
check_network() {
local test_urls=("github.com" "raw.githubusercontent.com")
for url in "${test_urls[@]}"; do
if ! ping -c 1 $url >/dev/null 2>&1; then
log_warn "无法访问 $url"
return 1
fi
done
return 0
}
# 获取镜像源
get_mirror_url() {
local original_url="$1"
local url_type="$2"
if check_network; then
echo "$original_url"
return 0
fi
case "$url_type" in
"github")
echo "https://ghproxy.com/$original_url"
;;
"omz")
echo "https://gitee.com/mirrors/oh-my-zsh/raw/master/tools/install.sh"
;;
*)
echo "$original_url"
;;
esac
}
# 配置文件管理
manage_config() {
local action="$1"
local config_file="$2"
local backup_dir="${USER_HOME}/.config_backups"
local timestamp=$(date +%Y%m%d_%H%M%S)
mkdir -p "$backup_dir"
case "$action" in
"backup")
if [ -f "$config_file" ]; then
local backup_file="${backup_dir}/$(basename ${config_file}).${timestamp}.bak"
cp "$config_file" "$backup_file"
LAST_BACKUP="$backup_file"
log_info "已备份 $config_file$backup_file"
fi
;;
"restore")
local source_file="$config_file"
if [ -f "$source_file" ]; then
local dest_file=$(echo "$source_file" | sed 's/\.[0-9]*_[0-9]*\.bak$//')
cp "$source_file" "$dest_file"
log_info "已恢复 $dest_file"
fi
;;
esac
}
# 插件管理
manage_plugin() {
local plugin_name="$1"
local plugin_dir="$2"
local plugin_url="$3"
show_progress "处理插件 $plugin_name"
if [ -d "$plugin_dir" ]; then
if [ -d "$plugin_dir/.git" ]; then
(cd "$plugin_dir" && git pull origin master >/dev/null 2>&1)
if [ $? -eq 0 ]; then
update_progress "处理插件 $plugin_name" "更新成功"
return 0
fi
fi
log_warn "更新 $plugin_name 失败,尝试重新安装"
rm -rf "$plugin_dir"
fi
if git clone --depth=1 "$plugin_url" "$plugin_dir" >/dev/null 2>&1; then
update_progress "处理插件 $plugin_name" "安装成功"
return 0
else
update_progress "处理插件 $plugin_name" "安装失败"
return 1
fi
}
# 依赖检查
check_dependencies() {
local deps=("$@")
local missing_deps=()
show_progress "检查依赖"
for dep in "${deps[@]}"; do
if ! command -v "$dep" >/dev/null 2>&1; then
missing_deps+=("$dep")
fi
done
if [ ${#missing_deps[@]} -ne 0 ]; then
update_progress "检查依赖" "发现缺失"
log_warn "缺少以下依赖: ${missing_deps[*]}"
log_info "正在安装缺失的依赖..."
apt-get update >/dev/null 2>&1
apt-get install -y "${missing_deps[@]}" >/dev/null 2>&1
update_progress "安装依赖" "完成"
else
update_progress "检查依赖" "已满足"
fi
}
# 用户交互
confirm() {
local msg="$1"
local default="${2:-Y}"
while true; do
read -p "$msg [Y/n] " response
response=${response:-$default}
case $response in
[Yy]) return 0 ;;
[Nn]) return 1 ;;
*) echo "请输入 y 或 n" ;;
esac
done
}
# 检查命令是否存在
check_command() {
if ! command -v "$1" &> /dev/null; then
log_error "命令 '$1' 未找到"
return 1
fi
return 0
}
# 检查是否为root用户
check_root() {
if [ "$EUID" -ne 0 ]; then
log_error "请使用root权限运行此脚本"
exit 1
fi
}
# 获取当前用户信息
get_user_info() {
CURRENT_USER=$SUDO_USER
if [ -z "$CURRENT_USER" ]; then
CURRENT_USER=$(who | awk '{print $1}' | head -n1)
fi
USER_HOME="/home/$CURRENT_USER"
# 验证用户信息
if ! id "$CURRENT_USER" >/dev/null 2>&1; then
log_error "无法获取用户信息: $CURRENT_USER"
exit 1
fi
if [ ! -d "$USER_HOME" ]; then
log_error "用户主目录不存在: $USER_HOME"
exit 1
fi
}
# 检查Node.js版本
check_nodejs() {
if command -v node &> /dev/null; then
local node_version=$(node -v | cut -d 'v' -f2)
if [ "$(echo -e "${node_version}\n16.0.0" | sort -V | head -n1)" = "16.0.0" ]; then
log_info "检测到 Node.js ${node_version},版本满足要求"
return 0
else
log_warn "当前 Node.js 版本 ${node_version} 过低,需要更新"
return 1
fi
else
log_warn "未检测到 Node.js"
return 1
fi
}
# 安装Node.js
install_nodejs() {
if ! check_nodejs; then
log_info "安装 Node.js..."
# 尝试使用 Debian 仓库安装
if apt-get install -y nodejs npm && check_nodejs; then
log_info "成功从 Debian 仓库安装 Node.js"
else
log_warn "从 Debian 仓库安装 Node.js 失败,尝试使用 NodeSource..."
# 删除可能存在的旧版本
apt-get remove -y nodejs npm
# 添加 NodeSource 仓库
mkdir -p /etc/apt/keyrings
curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg
echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list
apt-get update
apt-get install -y nodejs
fi
# 安装neovim包
su - $CURRENT_USER -c "npm install -g neovim"
fi
}
# 设置Python虚拟环境
setup_python_venv() {
local nvim_venv="${USER_HOME}/.local/share/nvim/venv"
# 创建虚拟环境
su - $CURRENT_USER -c "python3 -m venv ${nvim_venv}"
# 安装pynvim
su - $CURRENT_USER -c "${nvim_venv}/bin/pip install pynvim"
echo "${nvim_venv}"
}
# 下载文件的通用函数
download_file() {
local url="$1"
local output="$2"
local max_retries=3
local retry=0
local success=false
show_progress "下载 $(basename "$output")"
# 获取可能的镜像URL
local mirror_url=$(get_mirror_url "$url" "github")
while [ $retry -lt $max_retries ] && [ "$success" = false ]; do
if wget --no-check-certificate -q -O "$output" "$mirror_url" 2>/dev/null; then
success=true
elif curl -k -L -s -o "$output" "$mirror_url" 2>/dev/null; then
success=true
else
retry=$((retry + 1))
log_warn "下载失败,尝试重试 ($retry/$max_retries)..."
sleep 2
fi
done
if [ "$success" = false ]; then
update_progress "下载 $(basename "$output")" "失败"
return 1
fi
update_progress "下载 $(basename "$output")" "成功"
return 0
}
# 检查并安装基础依赖
install_base_dependencies() {
log_info "安装基础依赖..."
local base_deps=(
"git"
"curl"
"wget"
"unzip"
"python3-pip"
"python3-venv"
"build-essential"
"ca-certificates"
"fontconfig"
)
check_dependencies "${base_deps[@]}"
# 更新 CA 证书
update-ca-certificates >/dev/null 2>&1
}
# 安装字体
install_font() {
local font_url="$1"
local font_name="$2"
local font_dir="${USER_HOME}/.local/share/fonts"
show_progress "安装字体 $font_name"
# 创建字体目录
su - $CURRENT_USER -c "mkdir -p ${font_dir}"
# 下载并安装字体
if download_file "$font_url" "${font_dir}/${font_name}"; then
# 确保fontconfig已安装
ensure_package "fontconfig"
# 更新字体缓存
fc-cache -f -v >/dev/null 2>&1
update_progress "安装字体 $font_name" "完成"
return 0
else
update_progress "安装字体 $font_name" "失败"
return 1
fi
}
# 添加环境变量
add_env_var() {
local var_name="$1"
local var_value="$2"
local config_file="$3"
if ! grep -q "export ${var_name}=" "$config_file" 2>/dev/null; then
echo "export ${var_name}=\"${var_value}\"" >> "$config_file"
log_info "添加环境变量 ${var_name}=${var_value}"
fi
}
# 添加PATH
add_path() {
local new_path="$1"
local config_file="$2"
if ! grep -q "export PATH=.*${new_path}" "$config_file" 2>/dev/null; then
echo "export PATH=\"${new_path}:\$PATH\"" >> "$config_file"
log_info "添加PATH ${new_path}"
fi
}
# 添加别名
add_alias() {
local alias_name="$1"
local alias_value="$2"
local config_file="$3"
if ! grep -q "alias ${alias_name}=" "$config_file" 2>/dev/null; then
echo "alias ${alias_name}='${alias_value}'" >> "$config_file"
log_info "添加别名 ${alias_name}=${alias_value}"
fi
}
# 检查并创建目录
ensure_dir() {
local dir="$1"
local owner="${2:-}"
if [ ! -d "$dir" ]; then
mkdir -p "$dir"
if [ -n "$owner" ]; then
chown -R "$owner" "$dir"
fi
log_info "创建目录 $dir"
fi
}
# 检查并安装依赖包
ensure_package() {
local package="$1"
if ! dpkg -l | grep -q "^ii $package " 2>/dev/null; then
log_info "安装 $package..."
apt-get update >/dev/null 2>&1
apt-get install -y "$package" >/dev/null 2>&1
log_success "$package 安装完成"
fi
}
# 检查进程是否在运行
check_process() {
local process="$1"
if pgrep -x "$process" >/dev/null; then
return 0
fi
return 1
}
# 等待进程结束
wait_process() {
local process="$1"
local timeout="$2"
local count=0
while check_process "$process" && [ $count -lt $timeout ]; do
sleep 1
count=$((count + 1))
done
if check_process "$process"; then
return 1
fi
return 0
}
# 设置trap
trap cleanup EXIT