You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过shell脚本或yaml解决多服务启动时的命令阻塞问题

问题根因

Shell脚本默认按顺序逐行执行,只有当前行命令完全退出后,才会运行下一行命令。你脚本中的uvicorn main:app --reload --port 8000、npm start、npm run dev都是常驻前台的服务进程,启动后会一直持有终端会话,不会主动退出,因此脚本会卡在uvicorn启动这一步,后续命令永远不会被执行。

解决方法

方法1:调整Shell脚本逻辑,后台运行常驻服务

给所有不需要前台交互的常驻服务命令加上后台运行标识,同时把日志输出重定向到独立文件,避免不同服务的日志混杂。修改后的server.sh参考如下:

#!/bin/bash
set -e # 任意命令执行失败时直接退出脚本,避免后续逻辑在错误状态下运行

# 启动systemd托管的基础服务,这类命令执行完会自动退出,不会阻塞脚本
sudo systemctl start elasticsearch.service
sudo systemctl start kibana.service

# 启动FastAPI服务,后台运行,日志输出到当前目录下的fastapi.log
cd fastapi
nohup uvicorn main:app --reload --port 8000 > ../fastapi.log 2>&1 &
echo "FastAPI 服务已启动,监听8000端口,日志路径:./fastapi.log"

# 启动React前端服务,后台运行
cd ../reactjs
npm i
nohup npm start > ../reactjs.log 2>&1 &
echo "React 服务已启动,日志路径:./reactjs.log"

# 启动Node服务,如果你需要直接在当前终端看Node服务的实时日志,可以保持前台运行;需要全后台就和上面的写法一致
cd ../node
npm i
echo "Node 服务启动中,日志输出到当前终端"
npm run dev

关键参数说明:

  • 命令末尾加&:将进程放入后台运行,脚本无需等待进程退出,直接执行下一行
  • nohup:保证当前终端关闭后,后台启动的服务不会跟着被系统杀掉
  • > xxx.log 2>&1:将进程的普通输出、错误输出全部重定向到指定日志文件,避免日志乱刷
  • set -e:脚本运行过程中任意一步出错(比如目录不存在、依赖安装失败)就直接退出,不会带着错误继续往下跑

如果需要所有服务都在后台运行,把最后一行的npm run dev替换为nohup npm run dev > ../node.log 2>&1 &即可,脚本执行完会直接返回终端,需要看日志时直接查看对应log文件,要停服务可以通过ps aux | grep 服务名找到进程ID后手动kill。

方法2:用Docker Compose做服务编排(推荐长期使用)

如果不想手动管理后台进程、日志和进程启停,可以把所有服务打包成容器,通过yaml配置统一编排,一键启停。在项目根目录新建docker-compose.yml,参考配置如下:

version: '3.8'
services:
  elasticsearch:
    image: elasticsearch:对应你本地使用的版本号
    ports:
      - "9200:9200"
    environment:
      - discovery.type=single-node
      - ES_JAVA_OPTS=-Xms512m -Xmx512m
  kibana:
    image: kibana:对应你本地使用的版本号
    ports:
      - "5601:5601"
    depends_on:
      - elasticsearch
  fastapi:
    build: ./fastapi
    ports:
      - "8000:8000"
    volumes:
      - ./fastapi:/app
    command: uvicorn main:app --reload --host 0.0.0.0 --port 8000
    depends_on:
      - elasticsearch
  react:
    build: ./reactjs
    ports:
      - "3000:3000"
    volumes:
      - ./reactjs:/app
    command: sh -c "npm i && npm start"
    depends_on:
      - fastapi
  node:
    build: ./node
    ports:
      - "替换为你的node服务端口:替换为你的node服务端口"
    volumes:
      - ./node:/app
    command: sh -c "npm i && npm run dev"
    depends_on:
      - fastapi

配置完成后,只需要在项目根目录执行docker-compose up -d就能一次性启动所有服务,执行docker-compose down就能一次性停止并删除所有服务容器,不需要单独维护shell脚本的后台进程逻辑,也不会出现进程残留、日志混杂的问题。


内容的提问来源于stack exchange,提问作者Hariprasath Lakshmanan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 02:54:20