每次拿到崭新的树莓派设备,开发者们都会面临一系列重复的初始化配置工作——换源、安装必备工具、设置网络参数、配置开发环境。这些步骤看似简单,但当需要批量部署多台设备或在多个项目中重复使用时,手动操作不仅效率低下,还容易出错。本文将带你用Bash脚本将这些繁琐过程自动化,打造属于你自己的"树莓派配置工具箱"。
在物联网和边缘计算项目中,树莓派常以集群形式出现。想象一下,你需要为20台树莓派配置相同的开发环境:手动操作每台设备不仅耗时数小时,还难以保证配置一致性。更糟的是,当某个步骤出错时,你可能需要从头开始。
自动化脚本解决了三个核心痛点:
我曾为一个校园物联网项目部署15台树莓派,手动配置花了整整两天,而改用脚本后只需一杯咖啡的时间。这种效率差异在商业环境中意味着真金白银的成本节约。
一个专业的配置脚本不应是命令的简单堆砌,而需要考虑错误处理、依赖检查和用户交互。以下是脚本的基本框架:
bash复制#!/bin/bash
# 定义颜色代码用于输出美化
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# 检查脚本是否以root权限运行
if [ "$(id -u)" -ne 0 ]; then
echo -e "${RED}错误:此脚本需要root权限${NC}" >&2
exit 1
fi
# 记录日志函数
log() {
echo -e "${GREEN}[$(date '+%Y-%m-%d %H:%M:%S')] $1${NC}"
}
# 错误处理函数
error_exit() {
echo -e "${RED}[错误] $1${NC}" >&2
exit 1
}
这个基础框架提供了:
国内用户首先需要更换软件源。以下是一个安全的换源实现:
bash复制# 备份原有源
backup_sources() {
log "备份原有软件源..."
cp /etc/apt/sources.list /etc/apt/sources.list.bak
cp /etc/apt/sources.list.d/raspi.list /etc/apt/sources.list.d/raspi.list.bak
}
# 配置清华源
configure_tsinghua_source() {
log "配置清华镜像源..."
cat > /etc/apt/sources.list <<EOF
deb http://mirrors.tuna.tsinghua.edu.cn/raspbian/raspbian/ $(lsb_release -sc) main non-free contrib
deb-src http://mirrors.tuna.tsinghua.edu.cn/raspbian/raspbian/ $(lsb_release -sc) main non-free contrib
EOF
cat > /etc/apt/sources.list.d/raspi.list <<EOF
deb http://mirrors.tuna.tsinghua.edu.cn/raspberrypi/ $(lsb_release -sc) main ui
EOF
apt update || error_exit "更新软件源失败"
}
这个实现考虑了:
静态IP配置是另一个常见需求,但处理不当会导致网络不可用。以下是安全实现:
bash复制configure_static_ip() {
interface=$1
ip_address=$2
gateway=$3
dns=$4
# 验证IP格式
if ! [[ $ip_address =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/[0-9]+$ ]]; then
error_exit "IP地址格式不正确,应为x.x.x.x/x"
fi
log "配置静态IP: $ip_address 在接口 $interface"
cat >> /etc/dhcpcd.conf <<EOF
interface $interface
static ip_address=$ip_address
static routers=$gateway
static domain_name_servers=$dns
EOF
systemctl restart dhcpcd || error_exit "重启dhcpcd服务失败"
}
调用示例:
bash复制configure_static_ip wlan0 192.168.1.100/24 192.168.1.1 8.8.8.8
对于开发者,VSCode Server是常用工具。以下是自动安装脚本:
bash复制install_vscode_server() {
log "安装VSCode Server..."
commit_id="5437499feb04f7a586f677b155b039bc2b3669eb"
install_dir="$HOME/.vscode-server/bin/$commit_id"
mkdir -p "$install_dir" || error_exit "创建安装目录失败"
cd "$install_dir" || error_exit "进入安装目录失败"
wget "https://update.code.visualstudio.com/commit:$commit_id/server-linux-x64/stable" -O vscode-server-linux-x64.tar.gz \
|| error_exit "下载VSCode Server失败"
tar zxvf vscode-server-linux-x64.tar.gz --strip 1 || error_exit "解压失败"
rm vscode-server-linux-x64.tar.gz
log "VSCode Server安装完成"
}
基础功能实现后,我们需要增强脚本的健壮性和用户体验:
在关键操作前检查必要依赖:
bash复制check_dependencies() {
dependencies=("wget" "tar" "git")
missing=()
for dep in "${dependencies[@]}"; do
if ! command -v "$dep" &> /dev/null; then
missing+=("$dep")
fi
done
if [ ${#missing[@]} -ne 0 ]; then
log "安装缺失依赖: ${missing[*]}"
apt install -y "${missing[@]}" || error_exit "依赖安装失败"
fi
}
对于关键操作,添加用户确认:
bash复制ask_confirmation() {
local message=$1
echo -en "${YELLOW}$message (y/n): ${NC}"
read -r response
case "$response" in
[yY][eE][sS]|[yY])
return 0
;;
*)
return 1
;;
esac
}
# 使用示例
if ask_confirmation "确定要配置静态IP吗?"; then
configure_static_ip wlan0 192.168.1.100/24 192.168.1.1 8.8.8.8
fi
对于关键配置,实现简单的回滚机制:
bash复制rollback_network() {
log "正在回滚网络配置..."
cp /etc/dhcpcd.conf.bak /etc/dhcpcd.conf
systemctl restart dhcpcd
}
将各模块组合成完整脚本,结构如下:
code复制raspi-config-tool/
├── main.sh # 主入口脚本
├── modules/
│ ├── network.sh # 网络配置模块
│ ├── package.sh # 软件包管理
│ └── dev_env.sh # 开发环境配置
└── config/
├── hosts.list # 多主机配置
└── custom_packages.list # 自定义软件列表
主脚本通过source引入各模块:
bash复制#!/bin/bash
# 加载配置
source config/hosts.list
source config/custom_packages.list
# 加载模块
source modules/network.sh
source modules/package.sh
source modules/dev_env.sh
# 主菜单
show_menu() {
echo "1. 基础系统配置"
echo "2. 网络配置"
echo "3. 开发环境配置"
echo "4. 全部配置"
read -p "请选择: " option
case $option in
1) basic_config ;;
2) network_config ;;
3) dev_config ;;
4) full_config ;;
*) echo "无效选项" ;;
esac
}
main() {
check_dependencies
show_menu
}
main
这种模块化设计允许:
结合sshpass和parallel实现集群部署:
bash复制deploy_to_cluster() {
local script=$1
while read -r host; do
ip=$(echo "$host" | awk '{print $1}')
pass=$(echo "$host" | awk '{print $2}')
sshpass -p "$pass" scp "$script" pi@"$ip":/tmp/ \
&& sshpass -p "$pass" ssh pi@"$ip" "chmod +x /tmp/$script && sudo /tmp/$script" &
done < config/hosts.list
wait
log "集群部署完成"
}
将脚本与配置纳入Git管理:
bash复制setup_version_control() {
log "初始化版本控制..."
git init
cat > .gitignore <<EOF
*.bak
*.tmp
EOF
git add .
git commit -m "初始配置脚本版本"
}
使用envsubst实现配置模板化:
bash复制generate_config_from_template() {
export DEVICE_NAME="raspi-$(hostname)"
export TIMEZONE="Asia/Shanghai"
envsubst < templates/wpa_supplicant.template > /etc/wpa_supplicant/wpa_supplicant.conf
}
自动化脚本需要特别注意安全:
bash复制# 错误做法
PASSWORD="123456"
# 正确做法
read -sp "输入密码: " PASSWORD
权限最小化:
输入验证:
bash复制validate_ip() {
local ip=$1
if [[ $ip =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
return 0
else
return 1
fi
}
在实际项目中,我发现最常见的错误是网络配置后忘记验证连通性。一个简单的改进是在配置后添加ping测试:
bash复制test_network() {
if ping -c 3 8.8.8.8 &> /dev/null; then
log "网络测试通过"
else
error_exit "网络配置失败,无法连接外网"
fi
}