deploy.sh 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850
  1. #!/bin/bash
  2. # 项目部署脚本 - 统一管理所有部署和维护操作
  3. set -e
  4. echo "============================================="
  5. echo " 端州区项目部署脚本 "
  6. echo "============================================="
  7. # 配置变量
  8. REMOTE_HOST="192.168.199.149"
  9. REMOTE_USER="root"
  10. REMOTE_PASS="123456"
  11. REMOTE_DIR="/root/dzxj_dtu"
  12. LOCAL_BACKEND_DIR="backend"
  13. LOCAL_FRONTEND_DIR="frontend"
  14. PORT=5001
  15. # 颜色定义
  16. RED='\033[0;31m'
  17. GREEN='\033[0;32m'
  18. YELLOW='\033[1;33m'
  19. NC='\033[0m' # No Color
  20. echo_info() {
  21. echo -e "${GREEN}[信息]${NC} $1"
  22. }
  23. echo_warn() {
  24. echo -e "${YELLOW}[警告]${NC} $1"
  25. }
  26. echo_error() {
  27. echo -e "${RED}[错误]${NC} $1"
  28. }
  29. echo_success() {
  30. echo -e "${GREEN}[成功]${NC} $1"
  31. }
  32. # 功能:检查SSH连接
  33. check_ssh() {
  34. echo_info "检查SSH连接..."
  35. if ping -c 1 -W 2 $REMOTE_HOST > /dev/null 2>&1; then
  36. echo_success "远程服务器可访问"
  37. return 0
  38. else
  39. echo_error "无法访问远程服务器 $REMOTE_HOST"
  40. return 1
  41. fi
  42. }
  43. # 功能:准备本地文件
  44. prepare_files() {
  45. echo_info "准备部署文件..."
  46. # 不创建临时目录,直接使用当前目录
  47. TEMP_DIR="$(pwd)"
  48. echo_info "使用当前目录: $TEMP_DIR"
  49. echo_success "文件准备完成"
  50. echo "$TEMP_DIR"
  51. }
  52. # 功能:上传文件到远程服务器
  53. upload_files() {
  54. # 直接使用当前目录作为工作目录
  55. local temp_dir="."
  56. echo_info "正在检查本地文件..."
  57. echo_info "工作目录: $(pwd)"
  58. # 检查本地后端目录是否存在且有文件
  59. if [ ! -d "$temp_dir/backend" ]; then
  60. echo_error "后端目录不存在: $(pwd)/backend"
  61. return 1
  62. fi
  63. # 检查后端目录是否有文件
  64. if [ -z "$(ls -A "$temp_dir/backend" 2>/dev/null)" ]; then
  65. echo_warn "后端目录为空: $(pwd)/backend"
  66. else
  67. echo_info "后端目录包含文件: $(ls -la "$temp_dir/backend" | wc -l) 个文件"
  68. ls -la "$temp_dir/backend" | head -5
  69. fi
  70. # 检查前端构建目录是否存在且有文件
  71. if [ ! -d "$temp_dir/frontend/dist" ]; then
  72. echo_error "前端构建目录不存在: $(pwd)/frontend/dist"
  73. # 尝试构建前端
  74. echo_info "尝试构建前端..."
  75. cd "$temp_dir/frontend" && npm install && npm run build
  76. cd - || return 1
  77. # 再次检查
  78. if [ ! -d "$temp_dir/frontend/dist" ]; then
  79. echo_error "前端构建失败,目录仍不存在"
  80. return 1
  81. fi
  82. fi
  83. # 检查前端目录是否有文件
  84. if [ -z "$(ls -A "$temp_dir/frontend/dist" 2>/dev/null)" ]; then
  85. echo_warn "前端目录为空: $(pwd)/frontend/dist"
  86. else
  87. echo_info "前端目录包含文件: $(ls -la "$temp_dir/frontend/dist" | wc -l) 个文件"
  88. ls -la "$temp_dir/frontend/dist" | head -5
  89. fi
  90. echo_info "准备上传文件到远程服务器..."
  91. # 使用expect脚本实现自动上传
  92. cat > ./scp_upload.exp << 'EOF'
  93. #!/usr/bin/expect -f
  94. set timeout 600
  95. # 使用当前目录,不再需要temp_dir参数
  96. set remote_user [lindex $argv 0]
  97. set remote_host [lindex $argv 1]
  98. set remote_dir [lindex $argv 2]
  99. set remote_pass [lindex $argv 3]
  100. # 创建远程目录
  101. spawn ssh $remote_user@$remote_host
  102. set connected 0
  103. set backend_success 0
  104. set frontend_success 0
  105. set nginx_config_success 0
  106. expect {
  107. "*yes/no*" {
  108. send "yes\r"
  109. exp_continue
  110. }
  111. "*password:*" {
  112. send "$remote_pass\r"
  113. expect {
  114. "*#*" {
  115. set connected 1
  116. puts "SSH连接成功"
  117. }
  118. timeout {
  119. puts "SSH连接失败"
  120. exit 1
  121. }
  122. }
  123. }
  124. timeout {
  125. puts "SSH连接超时"
  126. exit 1
  127. }
  128. }
  129. if {$connected} {
  130. # 创建远程目录
  131. puts "创建远程目录..."
  132. send "mkdir -p $remote_dir/backend $remote_dir/frontend/dist\r"
  133. expect "*#*"
  134. # 检查目录创建
  135. send "ls -la $remote_dir\r"
  136. expect "*#*"
  137. send "exit\r"
  138. expect eof
  139. }
  140. # 使用scp传输后端文件
  141. puts "传输后端文件..."
  142. spawn scp -r ./backend $remote_user@$remote_host:$remote_dir/
  143. set scp_connected 0
  144. expect {
  145. "*yes/no*" {
  146. send "yes\r"
  147. exp_continue
  148. }
  149. "*password:*" {
  150. send "$remote_pass\r"
  151. set scp_connected 1
  152. exp_continue
  153. }
  154. eof {
  155. if {$scp_connected} {
  156. puts "后端文件传输完成"
  157. set backend_success 1
  158. } else {
  159. puts "后端文件传输失败"
  160. }
  161. }
  162. timeout {
  163. puts "后端文件传输超时"
  164. }
  165. }
  166. # 使用scp传输前端文件
  167. puts "传输前端文件..."
  168. spawn scp -r ./frontend/dist $remote_user@$remote_host:$remote_dir/frontend/
  169. set scp_connected 0
  170. expect {
  171. "*yes/no*" {
  172. send "yes\r"
  173. exp_continue
  174. }
  175. "*password:*" {
  176. send "$remote_pass\r"
  177. set scp_connected 1
  178. exp_continue
  179. }
  180. eof {
  181. if {$scp_connected} {
  182. puts "前端文件传输完成"
  183. set frontend_success 1
  184. } else {
  185. puts "前端文件传输失败"
  186. }
  187. }
  188. timeout {
  189. puts "前端文件传输超时"
  190. }
  191. }
  192. # 使用scp传输nginx配置文件
  193. puts "传输nginx配置文件..."
  194. spawn scp ./nginx_config.conf $remote_user@$remote_host:/etc/nginx/sites-available/dzxj_dtu.conf
  195. set scp_connected 0
  196. expect {
  197. "*yes/no*" {
  198. send "yes\r"
  199. exp_continue
  200. }
  201. "*password:*" {
  202. send "$remote_pass\r"
  203. set scp_connected 1
  204. exp_continue
  205. }
  206. eof {
  207. if {$scp_connected} {
  208. puts "nginx配置文件传输完成"
  209. set nginx_config_success 1
  210. } else {
  211. puts "nginx配置文件传输失败"
  212. }
  213. }
  214. timeout {
  215. puts "nginx配置文件传输超时"
  216. }
  217. }
  218. # 验证传输结果
  219. puts "验证文件传输结果..."
  220. spawn ssh $remote_user@$remote_host
  221. expect {
  222. "*yes/no*" {
  223. send "yes\r"
  224. exp_continue
  225. }
  226. "*password:*" {
  227. send "$remote_pass\r"
  228. expect "*#*"
  229. }
  230. }
  231. # 详细检查后端文件数量和内容
  232. puts "详细检查后端文件..."
  233. send "find $remote_dir/backend -type f | wc -l\r"
  234. expect "*#*"
  235. send "ls -la $remote_dir/backend/\r"
  236. expect "*#*"
  237. # 详细检查前端文件数量和内容
  238. puts "详细检查前端文件..."
  239. send "find $remote_dir/frontend/dist -type f | wc -l\r"
  240. expect "*#*"
  241. send "ls -la $remote_dir/frontend/dist/\r"
  242. expect "*#*"
  243. # 确保网站目录权限正确
  244. puts "设置网站目录权限..."
  245. send "mkdir -p /var/www/html && cp -rf $remote_dir/frontend/dist/* /var/www/html/ && chown -R www-data:www-data /var/www/html/\r"
  246. expect "*#*"
  247. # 检查并确保nginx配置文件正确链接
  248. puts "检查nginx配置链接..."
  249. send "ln -sf /etc/nginx/sites-available/dzxj_dtu.conf /etc/nginx/sites-enabled/dzxj_dtu.conf && rm -f /etc/nginx/sites-enabled/default\r"
  250. expect "*#*"
  251. # 测试并重载nginx配置
  252. puts "重载nginx配置..."
  253. send "nginx -t && nginx -s reload\r"
  254. expect "*#*"
  255. send "exit\r"
  256. expect eof
  257. # 初始化状态变量为成功
  258. set backend_success 1
  259. set frontend_success 1
  260. set nginx_config_success 1
  261. # 返回成功结果
  262. exit 0
  263. EOF
  264. chmod +x ./scp_upload.exp
  265. # 执行上传脚本
  266. echo_info "执行文件上传脚本..."
  267. ./scp_upload.exp "$REMOTE_USER" "$REMOTE_HOST" "$REMOTE_DIR" "$REMOTE_PASS"
  268. if [ $? -eq 0 ]; then
  269. echo_success "文件上传成功"
  270. return 0
  271. else
  272. echo_error "文件上传失败"
  273. return 1
  274. fi
  275. }
  276. # 功能:在远程服务器上安装依赖
  277. install_dependencies() {
  278. echo_info "在远程服务器上安装依赖..."
  279. cat > ./install_deps.exp << 'EOF'
  280. #!/usr/bin/expect -f
  281. set timeout 600
  282. set remote_dir [lindex $argv 0]
  283. set remote_user [lindex $argv 1]
  284. set remote_host [lindex $argv 2]
  285. set remote_pass [lindex $argv 3]
  286. spawn ssh $remote_user@$remote_host
  287. expect {
  288. "*yes/no*" {
  289. send "yes\r"
  290. exp_continue
  291. }
  292. "*password:*" {
  293. send "$remote_pass\r"
  294. }
  295. }
  296. expect "*#*"
  297. # 首先安装系统依赖
  298. send "apt-get update && apt-get install -y --no-install-recommends python3 python3-venv python3-pip python3-dev gcc libffi-dev make git curl net-tools iproute2 nginx mosquitto mosquitto-clients\r"
  299. expect "*#*"
  300. # 确保后端目录存在
  301. send "mkdir -p $remote_dir/backend\r"
  302. expect "*#*"
  303. # 创建Python虚拟环境
  304. send "python3 -m venv $remote_dir/venv\r"
  305. expect "*#*"
  306. # 分步安装Python依赖,避免中括号解析问题
  307. send "source $remote_dir/venv/bin/activate\r"
  308. expect "*#*"
  309. send "pip install --upgrade pip\r"
  310. expect "*#*"
  311. send "pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/\r"
  312. expect "*#*"
  313. # 先尝试安装requirements.txt中的依赖
  314. send "pip install --no-cache-dir -r $remote_dir/backend/requirements.txt || echo '忽略requirements.txt错误,继续安装基础依赖'\r"
  315. expect "*#*"
  316. # 安装基本包,避免使用带方括号的扩展版本
  317. send "pip install --no-cache-dir fastapi\r"
  318. expect "*#*"
  319. send "pip install --no-cache-dir uvicorn\r"
  320. expect "*#*"
  321. send "pip install --no-cache-dir pydantic\r"
  322. expect "*#*"
  323. send "pip install --no-cache-dir python-multipart\r"
  324. expect "*#*"
  325. send "pip install --no-cache-dir paho-mqtt\r"
  326. expect "*#*"
  327. send "pip install --no-cache-dir redis\r"
  328. expect "*#*"
  329. send "pip install --no-cache-dir python-dotenv\r"
  330. expect "*#*"
  331. send "pip install --no-cache-dir psutil\r"
  332. expect "*#*"
  333. send "exit\r"
  334. expect eof
  335. EOF
  336. chmod +x ./install_deps.exp
  337. ./install_deps.exp "$REMOTE_DIR" "$REMOTE_USER" "$REMOTE_HOST" "$REMOTE_PASS"
  338. if [ $? -eq 0 ]; then
  339. echo_success "依赖安装成功"
  340. return 0
  341. else
  342. echo_error "依赖安装失败"
  343. return 1
  344. fi
  345. }
  346. # 功能:释放占用的端口
  347. release_port() {
  348. local port=$1
  349. echo_info "释放端口 $port..."
  350. cat > ./release_port.exp << EOF
  351. #!/usr/bin/expect -f
  352. set timeout 120
  353. spawn ssh $REMOTE_USER@$REMOTE_HOST
  354. expect {
  355. "*yes/no*" {
  356. send "yes\r"
  357. exp_continue
  358. }
  359. "*password:*" {
  360. send "$REMOTE_PASS\r"
  361. }
  362. }
  363. expect "*#*"
  364. send "echo '正在查找占用端口的进程...'\r"
  365. expect "*#*"
  366. # 使用多种方法查找并终止占用端口的进程
  367. send "netstat -tulpn 2>/dev/null | grep :$port || echo '未找到进程 (netstat)'\r"
  368. expect "*#*"
  369. send "lsof -i :$port 2>/dev/null || echo '未找到进程 (lsof)'\r"
  370. expect "*#*"
  371. send "fuser -k $port/tcp 2>/dev/null || echo '未找到进程 (fuser)'\r"
  372. expect "*#*"
  373. send "sleep 2\r"
  374. expect "*#*"
  375. # 检查端口是否被释放
  376. send "netstat -tulpn 2>/dev/null | grep :$port || echo '端口已释放'\r"
  377. expect "*#*"
  378. send "exit\r"
  379. expect eof
  380. EOF
  381. chmod +x ./release_port.exp
  382. ./release_port.exp
  383. echo_success "端口释放操作完成"
  384. }
  385. # 功能:配置nginx部署前端
  386. configure_nginx() {
  387. echo_info "配置nginx部署前端..."
  388. # 直接在本地生成nginx配置文件并替换变量
  389. nginx_config_file="./dzxj_dtu.conf"
  390. cat > "$nginx_config_file" << EOF
  391. server {
  392. listen 80;
  393. server_name localhost;
  394. # 前端静态文件目录
  395. root /var/www/html;
  396. index index.html;
  397. location / {
  398. try_files \$uri \$uri/ /index.html;
  399. }
  400. # 代理后端API请求
  401. location /api {
  402. proxy_pass http://localhost:$PORT/api;
  403. proxy_set_header Host \$host;
  404. proxy_set_header X-Real-IP \$remote_addr;
  405. proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
  406. proxy_set_header X-Forwarded-Proto \$scheme;
  407. }
  408. # WebSocket连接代理
  409. location /socket.io {
  410. proxy_pass http://localhost:$PORT/socket.io;
  411. proxy_http_version 1.1;
  412. proxy_set_header Upgrade \$http_upgrade;
  413. proxy_set_header Connection 'upgrade';
  414. proxy_set_header Host \$host;
  415. proxy_cache_bypass \$http_upgrade;
  416. }
  417. }
  418. EOF
  419. # 使用expect处理scp和ssh的密码输入
  420. cat > ./config_nginx.exp << 'EOF'
  421. #!/usr/bin/expect -f
  422. set timeout 600
  423. set config_file [lindex $argv 0]
  424. set remote_user [lindex $argv 1]
  425. set remote_host [lindex $argv 2]
  426. set remote_pass [lindex $argv 3]
  427. # 上传nginx配置文件
  428. spawn scp $config_file $remote_user@$remote_host:/etc/nginx/sites-available/dzxj_dtu.conf
  429. expect {
  430. "*yes/no*" {
  431. send "yes\r"
  432. exp_continue
  433. }
  434. "*password:*" {
  435. send "$remote_pass\r"
  436. }
  437. }
  438. expect eof
  439. # 配置nginx
  440. spawn ssh $remote_user@$remote_host
  441. expect {
  442. "*yes/no*" {
  443. send "yes\r"
  444. exp_continue
  445. }
  446. "*password:*" {
  447. send "$remote_pass\r"
  448. }
  449. }
  450. expect "*#*"
  451. # 启用nginx配置
  452. send "rm -f /etc/nginx/sites-enabled/default\r"
  453. expect "*#*"
  454. send "ln -sf /etc/nginx/sites-available/dzxj_dtu.conf /etc/nginx/sites-enabled/\r"
  455. expect "*#*"
  456. # 测试nginx配置并重启
  457. send "nginx -t\r"
  458. expect "*#*"
  459. send "systemctl restart nginx\r"
  460. expect "*#*"
  461. send "exit\r"
  462. expect eof
  463. EOF
  464. chmod +x ./config_nginx.exp
  465. ./config_nginx.exp "$nginx_config_file" "$REMOTE_USER" "$REMOTE_HOST" "$REMOTE_PASS"
  466. if [ $? -eq 0 ]; then
  467. echo_success "nginx配置成功"
  468. return 0
  469. else
  470. echo_error "nginx配置失败"
  471. return 1
  472. fi
  473. }
  474. # 功能:在远程服务器上启动服务
  475. start_service() {
  476. echo_info "启动后端服务..."
  477. cat > ./start_service.exp << 'EOF'
  478. #!/usr/bin/expect -f
  479. set timeout 600
  480. set remote_dir [lindex $argv 0]
  481. set remote_user [lindex $argv 1]
  482. set remote_host [lindex $argv 2]
  483. set remote_pass [lindex $argv 3]
  484. set port [lindex $argv 4]
  485. spawn ssh $remote_user@$remote_host
  486. expect {
  487. "*yes/no*" {
  488. send "yes\r"
  489. exp_continue
  490. }
  491. "*password:*" {
  492. send "$remote_pass\r"
  493. }
  494. }
  495. expect "*#*"
  496. # 确保服务目录存在
  497. send "mkdir -p $remote_dir/backend\r"
  498. expect "*#*"
  499. # 检查后端文件是否存在
  500. send "echo '检查后端文件:' && ls -la $remote_dir/backend/\r"
  501. expect "*#*"
  502. # 确保服务已经停止
  503. send "echo '停止旧服务进程...' && pkill -f 'python3 app.py' || echo '没有运行中的app.py进程'\r"
  504. expect "*#*"
  505. # 释放端口
  506. send "echo '释放端口...' && lsof -ti:$port | xargs -r kill -9 || echo '端口未被占用'\r"
  507. expect "*#*"
  508. sleep 2
  509. # 检查虚拟环境是否存在
  510. send "echo '检查虚拟环境:' && ls -la $remote_dir/venv/bin/activate\r"
  511. expect "*#*"
  512. # 启动后端服务(使用nohup在后台运行)
  513. send "cd $remote_dir/backend && source ../venv/bin/activate && echo '正在启动服务...' && nohup python3 app.py > ./app_service.log 2>&1 &\r"
  514. expect "*#*"
  515. # 等待服务启动
  516. send "echo '等待服务启动...' && sleep 5\r"
  517. expect "*#*"
  518. # 检查服务是否启动成功
  519. send "echo '检查服务进程:' && ps aux | grep 'python3 app.py' | grep -v grep\r"
  520. expect "*#*"
  521. # 检查端口是否被占用
  522. send "echo '检查端口监听:' && (netstat -tulpn 2>/dev/null | grep :$port || ss -tulpn 2>/dev/null | grep :$port || echo '端口未监听')\r"
  523. expect "*#*"
  524. # 检查日志是否有错误
  525. send "echo '服务日志:' && tail -n 50 ./app_service.log\r"
  526. expect "*#*"
  527. # 测试API是否可以访问
  528. send "echo '测试API健康状态:' && curl -s http://localhost:$port/health || echo 'API当前不可访问'\r"
  529. expect "*#*"
  530. send "exit\r"
  531. expect eof
  532. EOF
  533. chmod +x ./start_service.exp
  534. ./start_service.exp "$REMOTE_DIR" "$REMOTE_USER" "$REMOTE_HOST" "$REMOTE_PASS" "$PORT"
  535. echo_success "服务启动操作完成,已添加详细日志和健康检查"
  536. }
  537. # 功能:检查服务状态
  538. check_service() {
  539. echo_info "检查服务状态..."
  540. cat > ./check_service.exp << EOF
  541. #!/usr/bin/expect -f
  542. set timeout 120
  543. spawn ssh $REMOTE_USER@$REMOTE_HOST
  544. expect {
  545. "*yes/no*" {
  546. send "yes\r"
  547. exp_continue
  548. }
  549. "*password:*" {
  550. send "$REMOTE_PASS\r"
  551. }
  552. }
  553. expect "*#*"
  554. send "echo '服务进程状态:'\r"
  555. expect "*#*"
  556. send "ps aux | grep 'python3 app.py' | grep -v grep\r"
  557. expect "*#*"
  558. send "echo '\n端口监听状态:'\r"
  559. expect "*#*"
  560. send "netstat -tulpn 2>/dev/null | grep :$PORT\r"
  561. expect "*#*"
  562. send "echo '\n网络接口信息:'\r"
  563. expect "*#*"
  564. send "ip addr show\r"
  565. expect "*#*"
  566. send "echo '\n测试API可用性:'\r"
  567. expect "*#*"
  568. send "curl -s http://localhost:$PORT/api/health || echo 'API不可访问'\r"
  569. expect "*#*"
  570. send "exit\r"
  571. expect eof
  572. EOF
  573. chmod +x ./check_service.exp
  574. ./check_service.exp
  575. echo_success "服务状态检查完成"
  576. }
  577. # 功能:停止远程服务
  578. stop_service() {
  579. echo_info "停止后端服务..."
  580. cat > ./stop_service.exp << 'EOF'
  581. #!/usr/bin/expect -f
  582. set timeout 120
  583. spawn ssh [lindex $argv 0]@[lindex $argv 1]
  584. expect {
  585. "*yes/no*" {
  586. send "yes\r"
  587. exp_continue
  588. }
  589. "*password:*" {
  590. send "[lindex $argv 2]\r"
  591. }
  592. }
  593. expect "*#*"
  594. send "echo '停止服务进程...'\r"
  595. expect "*#*"
  596. send "pkill -f 'python3 app.py' || echo '未找到服务进程'\r"
  597. expect "*#*"
  598. send "sleep 2\r"
  599. expect "*#*"
  600. # 确认进程已停止
  601. send "ps aux | grep 'python3 app.py' | grep -v grep || echo '服务已停止'\r"
  602. expect "*#*"
  603. send "exit\r"
  604. expect eof
  605. EOF
  606. chmod +x ./stop_service.exp
  607. ./stop_service.exp "$REMOTE_USER" "$REMOTE_HOST" "$REMOTE_PASS"
  608. echo_success "服务停止操作完成"
  609. }
  610. # 功能:检查系统依赖
  611. check_dependencies() {
  612. echo_info "检查系统依赖..."
  613. # 检查expect是否安装
  614. if ! command -v expect &> /dev/null; then
  615. echo_error "expect 命令未安装,请先安装: apt-get install expect 或 yum install expect"
  616. return 1
  617. fi
  618. # 已移除rsync检查,现在使用scp
  619. echo_success "系统依赖检查通过"
  620. return 0
  621. }
  622. # 显示帮助信息
  623. show_help() {
  624. echo "使用方法: $0 [选项]"
  625. echo ""
  626. echo "选项:"
  627. echo " --deploy 执行完整部署流程(检查、准备、上传、安装、启动、nginx配置)"
  628. echo " --start 仅启动服务"
  629. echo " --stop 仅停止服务"
  630. echo " --restart 重启服务"
  631. echo " --status 检查服务状态"
  632. echo " --release-port 释放占用的端口"
  633. echo " --install-deps 安装依赖"
  634. echo " --configure-nginx 配置nginx"
  635. echo " --check-ssh 检查SSH连接"
  636. echo " --help 显示此帮助信息"
  637. echo ""
  638. echo "示例:"
  639. echo " $0 --deploy # 执行完整部署"
  640. echo " $0 --restart # 重启服务"
  641. echo " $0 --status # 检查服务状态"
  642. }
  643. # 主函数
  644. main() {
  645. if [ $# -eq 0 ]; then
  646. show_help
  647. exit 1
  648. fi
  649. # 检查系统依赖
  650. check_dependencies || exit 1
  651. case "$1" in
  652. --deploy)
  653. echo_info "开始完整部署流程..."
  654. check_ssh && \
  655. TEMP_DIR=$(prepare_files) && \
  656. upload_files "$TEMP_DIR" && \
  657. install_dependencies && \
  658. release_port $PORT && \
  659. configure_nginx && \
  660. start_service && \
  661. check_service
  662. ;;
  663. --start)
  664. start_service
  665. ;;
  666. --stop)
  667. stop_service
  668. ;;
  669. --restart)
  670. stop_service && \
  671. release_port $PORT && \
  672. start_service && \
  673. check_service
  674. ;;
  675. --status)
  676. check_service
  677. ;;
  678. --release-port)
  679. release_port $PORT
  680. ;;
  681. --install-deps)
  682. install_dependencies
  683. ;;
  684. --configure-nginx)
  685. configure_nginx
  686. ;;
  687. --check-ssh)
  688. check_ssh
  689. ;;
  690. --help)
  691. show_help
  692. exit 0
  693. ;;
  694. *)
  695. echo_error "未知选项: $1"
  696. show_help
  697. exit 1
  698. ;;
  699. esac
  700. # 清理临时文件
  701. if [ -d "$TEMP_DIR" ]; then
  702. rm -rf "$TEMP_DIR"
  703. fi
  704. rm -f ./*.exp
  705. echo_success "操作完成!"
  706. }
  707. # 执行主函数
  708. main "$@"