文章目录
- 一、创建test1-test10用户(跳过已存在的test3)
- 二、检查必要组件是否安装
- 解决方法:用紧凑格式避免换行解析错误
- 核心修复说明:
- 使用方法:
以下是根据需求生成的命令、检查脚本及启动脚本,按步骤执行即可:
一、创建test1-test10用户(跳过已存在的test3)
# 循环创建用户,若用户已存在则跳过
for U in test1 test2 test3 test4 test5 test6 test7 test8 test9 test10; doif ! id "$U" &>/dev/null; then# 用户不存在时创建,家目录自动生成,默认shell为bashuseradd -m -s /bin/bash "$U"# 为新用户设置密码(可根据需要修改密码)echo "$U:StrongPassword123" | chpasswdecho "用户 $U 创建完成"elseecho "用户 $U 已存在,跳过创建"fi
done
二、检查必要组件是否安装
创建检查脚本 check_dependencies.sh
,用于验证 code-server
、jupyterlab
、jupyter-server-proxy
是否安装:
#!/bin/bash# 检查code-server是否安装
if command -v code-server &>/dev/null; thenecho "✅ code-server 已安装,版本:$(code-server --version | head -n1)"
elseecho "❌ code-server 未安装,请先执行安装命令:curl -fsSL https://code-server.dev/install.sh | sh"
fi# 检查jupyterlab是否安装
if command -v jupyter &>/dev/null && jupyter lab --version &>/dev/null; thenecho "✅ JupyterLab 已安装,版本:$(jupyter lab --version)"
elseecho "❌ JupyterLab 未安装,请先执行安装命令:pip install jupyterlab"
fi# 检查jupyter-server-proxy是否安装
if pip show jupyter-server-proxy &>/dev/null; thenecho "✅ jupyter-server-proxy 已安装,版本:$(pip show jupyter-server-proxy | grep Version | awk '{print $2}')"
elseecho "❌ jupyter-server-proxy 未安装,请先执行安装命令:pip install jupyter-server-proxy"
fi# 检查jupyter-server-proxy扩展是否启用
if jupyter server extension list 2>/dev/null | grep -q "jupyter_server_proxy.*enabled"; thenecho "✅ jupyter-server-proxy 扩展已启用"
elseecho "❌ jupyter-server-proxy 扩展未启用,请执行:jupyter server extension enable --sys-prefix jupyter_server_proxy"
fi
执行检查脚本:
chmod +x check_dependencies.sh
./check_dependencies.sh
根据输出提示,安装缺失的组件(若有)。
错误原因:su -c
命令中换行符和引号的组合导致命令被拆分成多行执行,使得 --bind-addr
被误认为独立命令(而非 code-server
的参数)。核心是命令格式的语法问题。
解决方法:用紧凑格式避免换行解析错误
将 code-server
的启动命令合并为单行(或严格控制换行位置),确保所有参数都属于 code-server
命令。以下是修复后的脚本(直接复制粘贴生成):
cat << 'EOF' > start_multi_user_ide_v2.sh
#!/bin/bash
set -euo pipefail# 配置参数
USERS=(test1 test2 test3 test4 test5 test6 test7 test8 test9 test10)
BASE_PORT=8890
JUPYTER_PORT=8910
JUPYTER_CONFIG_DIR="/opt/conda/etc/jupyter/jupyter_server_config.d"
CHECK_DELAY=2# 步骤1:配置Jupyter代理
echo "🔧 配置Jupyter代理允许的端口(${BASE_PORT}-$((BASE_PORT+9)))..."
mkdir -p "$JUPYTER_CONFIG_DIR"
cat > "$JUPYTER_CONFIG_DIR/proxy-allowed-ports.json" << 'EOF_INNER'
{"ServerProxy": {"allowed_ports": [8890,8891,8892,8893,8894,8895,8896,8897,8898,8899]}
}
EOF_INNER
echo "✅ Jupyter代理配置已更新"# 步骤2:启动各用户Code-Server(修复命令格式)
echo -e "\n🚀 开始启动各用户Code-Server..."
for idx in "${!USERS[@]}"; doUSER="${USERS[$idx]}"PORT=$((BASE_PORT + idx))HOME_DIR="/home/${USER}"DATA_DIR="${HOME_DIR}/.local/share/code-server"EXT_DIR="${HOME_DIR}/.local/share/code-server/extensions"LOG_FILE="${HOME_DIR}/code-server.log"CONFIG_FILE="${HOME_DIR}/.config/code-server/config.yaml"# 检查家目录if [ ! -d "$HOME_DIR" ]; thenecho "❌ 跳过用户${USER}:家目录不存在"continuefi# 备份旧配置if [ -f "$CONFIG_FILE" ]; thenecho "⚠️ 备份用户${USER}旧配置文件..."mv "$CONFIG_FILE" "${CONFIG_FILE}.bak"fi# 创建目录并授权echo "📂 准备用户${USER}目录..."mkdir -p "${DATA_DIR}" "${EXT_DIR}"chown -R "${USER}:${USER}" "${HOME_DIR}/.local" || {echo "❌ 用户${USER}目录授权失败"continue}# 停止旧进程if ss -ltnp | grep -q ":${PORT} "; thenecho "🔌 关闭端口${PORT}旧进程..."pkill -9 -f "code-server.*:${PORT}" || echo "⚠️ 无旧进程"sleep $CHECK_DELAYfi# 核心修复:用单行紧凑格式传递命令,避免换行解析错误echo "▶️ 启动用户${USER}(端口${PORT})..."su - "$USER" -c "nohup code-server --auth none --bind-addr 127.0.0.1:${PORT} --user-data-dir '${DATA_DIR}' --extensions-dir '${EXT_DIR}' --config /dev/null '${HOME_DIR}' > '${LOG_FILE}' 2>&1 & sleep 1" || {echo "❌ 用户${USER}启动命令执行失败,日志:${LOG_FILE}"continue}# 检查启动状态sleep $CHECK_DELAYif ss -ltnp | grep -q "127.0.0.1:${PORT}"; thenecho "✅ 用户${USER}启动成功"elseecho "❌ 用户${USER}启动失败!日志:"tail -n 5 "$LOG_FILE"fi
done# 步骤3:启动JupyterLab
echo -e "\n🌐 启动JupyterLab(端口${JUPYTER_PORT})..."
if ss -ltnp | grep -q ":${JUPYTER_PORT} "; thenecho "🔌 关闭Jupyter旧进程..."pkill -9 -f "jupyter-lab.*:${JUPYTER_PORT}"sleep $CHECK_DELAY
finohup jupyter lab \--ip=0.0.0.0 \--port="${JUPYTER_PORT}" \--allow-root \
> /var/log/jupyterlab.log 2>&1 &sleep $((CHECK_DELAY * 2))
if ss -ltnp | grep -q ":${JUPYTER_PORT} "; thenecho "✅ JupyterLab启动成功"
elseecho "❌ JupyterLab启动失败,日志:"tail -n 5 /var/log/jupyterlab.log
fi# 汇总结果
echo -e "\n📊 启动结果汇总:"
echo "Code-Server监听情况:"
ss -ltnp | grep -E ":889[0-9] " || echo "⚠️ 未发现监听端口"echo -e "\n🌐 访问地址:"
echo "JupyterLab:http://36.151.192.85:23589/lab?token=$(grep -oP 'token=\K[^&]+' /var/log/jupyterlab.log | head -n1)"
echo "test1 Code-Server:http://36.151.192.85:23589/proxy/8890/"
EOF
核心修复说明:
将 su -c
中的 code-server
命令改为单行紧凑格式,避免因换行导致的参数拆分:
原多行命令容易被shell解析为多个独立命令,而单行格式确保 --auth none
、--bind-addr
等参数都属于 code-server
命令,解决“--bind-addr: command not found
”错误。
使用方法:
- 复制上面的命令粘贴到终端,自动生成脚本。
- 运行脚本:
chmod +x start_multi_user_ide_v2.sh ./start_multi_user_ide_v2.sh
此时 code-server
会正确接收所有参数,免密启动并监听对应端口。