脚本
#!/bin/bash
#==============================================================================
# PostgreSQL 自动化安装配置脚本 (Ubuntu)
# 版本:2.2 (完全修复版)
#==============================================================================
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
# 日志文件
LOG_FILE="/var/log/postgresql-installer.log"
#==============================================================================
# 工具函数
#==============================================================================
print_message() {
local type=$1
shift
local message="$@"
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
case $type in
"success")
echo -e "${GREEN}✓ $message${NC}"
echo "[$timestamp] SUCCESS: $message" >> $LOG_FILE
;;
"error")
echo -e "${RED}✗ $message${NC}"
echo "[$timestamp] ERROR: $message" >> $LOG_FILE
;;
"warning")
echo -e "${YELLOW}⚠ $message${NC}"
echo "[$timestamp] WARNING: $message" >> $LOG_FILE
;;
"info")
echo -e "${BLUE}ℹ $message${NC}"
echo "[$timestamp] INFO: $message" >> $LOG_FILE
;;
esac
}
check_result() {
if [ $? -eq 0 ]; then
print_message "success" "$1"
return 0
else
print_message "error" "$2"
return 1
fi
}
check_root() {
if [ "$EUID" -ne 0 ]; then
print_message "error" "请使用 root 权限运行此脚本"
print_message "info" "请使用: sudo bash $0"
exit 1
fi
}
check_system() {
if [ ! -f /etc/os-release ]; then
print_message "error" "无法识别系统类型"
exit 1
fi
source /etc/os-release
if [ "$ID" != "ubuntu" ]; then
print_message "error" "此脚本仅支持 Ubuntu 系统"
print_message "info" "当前系统: $NAME $VERSION"
exit 1
fi
print_message "success" "系统检测通过: $PRETTY_NAME"
}
install_dependencies() {
print_message "info" "安装必要的依赖工具..."
apt update >/dev/null 2>&1
apt install -y whiptail dialog curl gnupg2 lsb-release >/dev/null 2>&1
check_result "依赖工具安装完成" "依赖工具安装失败"
}
#==============================================================================
# PostgreSQL 安装函数
#==============================================================================
check_postgresql_installed() {
if command -v psql >/dev/null 2>&1; then
return 0
else
return 1
fi
}
install_postgresql() {
local install_method=$1
if check_postgresql_installed; then
if ! whiptail --title "检测到已安装" --yesno "PostgreSQL 已安装,是否重新安装?" 10 60; then
return 0
fi
fi
print_message "info" "开始安装 PostgreSQL..."
if [ "$install_method" == "official" ]; then
print_message "info" "添加 PostgreSQL 官方仓库..."
install -d /usr/share/postgresql-common/pgdg
curl -o /usr/share/postgresql-common/pgdg/apt.postgresql.org.asc --fail https://www.postgresql.org/media/keys/ACCC4CF8.asc 2>/dev/null
echo "deb [signed-by=/usr/share/postgresql-common/pgdg/apt.postgresql.org.asc] https://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list
apt update >/dev/null 2>&1
apt install -y postgresql-16 postgresql-contrib-16 2>&1 | tee -a $LOG_FILE
else
apt update >/dev/null 2>&1
apt install -y postgresql postgresql-contrib 2>&1 | tee -a $LOG_FILE
fi
check_result "PostgreSQL 安装成功" "PostgreSQL 安装失败"
systemctl enable postgresql >/dev/null 2>&1
systemctl start postgresql >/dev/null 2>&1
check_result "PostgreSQL 服务已启动" "PostgreSQL 服务启动失败"
}
configure_password() {
local password=$1
print_message "info" "配置 postgres 用户密码..."
sudo -u postgres psql -c "ALTER USER postgres PASSWORD '$password';" 2>&1 | tee -a $LOG_FILE
check_result "密码配置成功" "密码配置失败"
}
configure_remote_access() {
local pg_version=$(ls /etc/postgresql/ 2>/dev/null | head -n 1)
if [ -z "$pg_version" ]; then
print_message "error" "未找到 PostgreSQL 配置目录"
return 1
fi
local config_dir="/etc/postgresql/$pg_version/main"
print_message "info" "配置远程访问..."
cp $config_dir/postgresql.conf $config_dir/postgresql.conf.backup 2>/dev/null
cp $config_dir/pg_hba.conf $config_dir/pg_hba.conf.backup 2>/dev/null
sed -i "s/#listen_addresses = 'localhost'/listen_addresses = '*'/" $config_dir/postgresql.conf
sed -i "s/listen_addresses = 'localhost'/listen_addresses = '*'/" $config_dir/postgresql.conf
if ! grep -q "host.*all.*all.*0.0.0.0/0.*md5" $config_dir/pg_hba.conf; then
echo "" >> $config_dir/pg_hba.conf
echo "# 允许远程连接" >> $config_dir/pg_hba.conf
echo "host all all 0.0.0.0/0 md5" >> $config_dir/pg_hba.conf
fi
systemctl restart postgresql
check_result "远程访问配置成功" "远程访问配置失败"
}
configure_firewall() {
print_message "info" "配置防火墙..."
if command -v ufw >/dev/null 2>&1; then
ufw allow 5432/tcp >/dev/null 2>&1
ufw reload >/dev/null 2>&1
check_result "防火墙配置成功 (UFW)" "防火墙配置失败"
elif command -v firewall-cmd >/dev/null 2>&1; then
firewall-cmd --permanent --add-port=5432/tcp >/dev/null 2>&1
firewall-cmd --reload >/dev/null 2>&1
check_result "防火墙配置成功 (firewalld)" "防火墙配置失败"
else
print_message "warning" "未检测到防火墙,跳过配置"
fi
}
install_pgadmin() {
print_message "info" "开始安装 pgAdmin4 Web..."
curl -fsS https://www.pgadmin.org/static/packages_pgadmin_org.pub | gpg --dearmor -o /usr/share/keyrings/packages-pgadmin-org.gpg 2>/dev/null
echo "deb [signed-by=/usr/share/keyrings/packages-pgadmin-org.gpg] https://ftp.postgresql.org/pub/pgadmin/pgadmin4/apt/$(lsb_release -cs) pgadmin4 main" > /etc/apt/sources.list.d/pgadmin4.list
apt update >/dev/null 2>&1
apt install -y pgadmin4-web 2>&1 | tee -a $LOG_FILE
check_result "pgAdmin4 安装成功" "pgAdmin4 安装失败" || return 1
local email=$(whiptail --title "pgAdmin 配置" --inputbox "请输入管理员邮箱:" 10 60 "admin@example.com" 3>&1 1>&2 2>&3)
local password=$(whiptail --title "pgAdmin 配置" --passwordbox "请输入管理员密码:" 10 60 3>&1 1>&2 2>&3)
if [ -z "$email" ] || [ -z "$password" ]; then
print_message "warning" "取消 pgAdmin 配置"
return 1
fi
print_message "info" "配置 pgAdmin..."
echo -e "$email\n$password\n$password\ny" | /usr/pgadmin4/bin/setup-web.sh 2>&1 | tee -a $LOG_FILE
check_result "pgAdmin4 配置完成" "pgAdmin4 配置失败"
}
show_installation_info() {
local password=$1
local server_ip=$(hostname -I | awk '{print $1}')
local pg_version=$(psql --version 2>/dev/null | awk '{print $3}')
local pg_status=$(systemctl is-active postgresql 2>/dev/null)
whiptail --title "安装完成" --msgbox "PostgreSQL 安装配置完成!
服务信息
========================================
版本: ${pg_version:-未知}
状态: ${pg_status:-未知}
端口: 5432
连接信息
========================================
本地连接:
psql -U postgres -h localhost
远程连接:
psql -U postgres -h $server_ip -p 5432
用户名: postgres
密码: $password
管理命令
========================================
启动: sudo systemctl start postgresql
停止: sudo systemctl stop postgresql
重启: sudo systemctl restart postgresql
状态: sudo systemctl status postgresql
日志文件: $LOG_FILE" 28 70
}
#==============================================================================
# 主菜单
#==============================================================================
show_main_menu() {
while true; do
CHOICE=$(whiptail --title "PostgreSQL 自动化安装配置工具 v2.2" --menu "请选择操作:" 22 70 12 "1" "系统检测" "2" "安装 PostgreSQL (Ubuntu源)" "3" "安装 PostgreSQL (官方源)" "4" "配置数据库密码" "5" "配置远程访问" "6" "配置防火墙" "7" "安装 pgAdmin4" "8" "一键完整安装" "9" "查看状态信息" "0" "退出程序" 3>&1 1>&2 2>&3)
exitstatus=$?
if [ $exitstatus != 0 ]; then
print_message "info" "用户取消操作"
exit 0
fi
case $CHOICE in
1)
check_system
whiptail --title "系统信息" --msgbox "$(cat /etc/os-release)" 20 70
;;
2)
install_postgresql "ubuntu"
;;
3)
install_postgresql "official"
;;
4)
PASSWORD=$(whiptail --title "设置密码" --passwordbox "请输入 postgres 用户密码:" 10 60 3>&1 1>&2 2>&3)
if [ -n "$PASSWORD" ]; then
configure_password "$PASSWORD"
else
whiptail --title "提示" --msgbox "密码不能为空" 8 50
fi
;;
5)
if whiptail --title "确认操作" --yesno "是否配置远程访问?\n\n警告: 这将允许外部访问数据库\n建议仅在受信任网络中使用" 12 60; then
configure_remote_access
fi
;;
6)
configure_firewall
;;
7)
install_pgadmin
;;
8)
INSTALL_METHOD=$(whiptail --title "选择安装源" --menu "请选择安装源:" 15 60 2 "ubuntu" "Ubuntu 官方源 (稳定)" "official" "PostgreSQL 官方源 (最新)" 3>&1 1>&2 2>&3)
if [ $? != 0 ]; then
continue
fi
PASSWORD=$(whiptail --title "设置密码" --passwordbox "请输入 postgres 用户密码:" 10 60 3>&1 1>&2 2>&3)
if [ -z "$PASSWORD" ]; then
whiptail --title "错误" --msgbox "密码不能为空,安装终止" 8 50
continue
fi
if whiptail --title "远程访问" --yesno "是否配置远程访问?" 10 60; then
ENABLE_REMOTE=1
else
ENABLE_REMOTE=0
fi
if whiptail --title "pgAdmin" --yesno "是否安装 pgAdmin4?" 10 60; then
INSTALL_PGADMIN=1
else
INSTALL_PGADMIN=0
fi
install_postgresql "$INSTALL_METHOD"
configure_password "$PASSWORD"
[ $ENABLE_REMOTE -eq 1 ] && configure_remote_access
configure_firewall
[ $INSTALL_PGADMIN -eq 1 ] && install_pgadmin
show_installation_info "$PASSWORD"
;;
9)
PG_VERSION=$(psql --version 2>/dev/null | awk '{print $3}' || echo "未安装")
PG_STATUS=$(systemctl is-active postgresql 2>/dev/null || echo "未运行")
PG_ENABLED=$(systemctl is-enabled postgresql 2>/dev/null || echo "未设置")
PG_CONNECTIONS=$(ss -tulnp 2>/dev/null | grep 5432 | wc -l)
SERVER_IP=$(hostname -I | awk '{print $1}')
INFO="PostgreSQL 状态信息
========================================
版本: $PG_VERSION
服务状态: $PG_STATUS
开机启动: $PG_ENABLED
端口监听: $PG_CONNECTIONS 个连接
服务器IP: $SERVER_IP
========================================"
whiptail --title "状态信息" --msgbox "$INFO" 15 60
;;
0)
print_message "info" "感谢使用,再见!"
exit 0
;;
*)
exit 0
;;
esac
done
}
#==============================================================================
# 主程序入口
#==============================================================================
main() {
clear
echo -e "${BLUE}"
echo "╔═══════════════════════════════════════════════════════╗"
echo "║ PostgreSQL 自动化安装配置工具 v2.2 ║"
echo "║ 支持: Ubuntu 20.04/22.04/24.04 LTS ║"
echo "╚═══════════════════════════════════════════════════════╝"
echo -e "${NC}"
touch $LOG_FILE 2>/dev/null
chmod 666 $LOG_FILE 2>/dev/null
print_message "info" "脚本启动时间: $(date '+%Y-%m-%d %H:%M:%S')"
check_root
check_system
install_dependencies
show_main_menu
}
main
🚀 使用步骤
# 删除旧文件
rm -f postgresql-installer.sh
# 创建新文件
cat > postgresql-installer.sh << 'EOF'
# 这里粘贴上面的完整脚本
EOF
# 或者用 nano 编辑器
nano postgresql-installer.sh
# 粘贴代码后按 Ctrl+O 保存,Ctrl+X 退出
# 赋予执行权限
chmod +x postgresql-installer.sh
# 运行
sudo ./postgresql-installer.sh