GPU_GUARD_MONOREPO/scripts/check-ports.js
2026-05-20 21:39:12 +08:00

94 lines
2.3 KiB
JavaScript

/**
* 端口检测和清理脚本
* 启动服务前检查并清理占用端口的进程
*/
const { exec, spawn } = require('child_process');
const netstat = (cmd) => new Promise((resolve) => {
exec(cmd, { shell: true }, (err, stdout) => resolve(stdout));
});
const PORTS = [
{ port: 8003, name: 'Backend' },
{ port: 9001, name: 'Frontend' },
];
async function getProcessesUsingPort(port) {
try {
const output = await netstat(`netstat -ano | findstr :${port}`);
const lines = output.trim().split('\n').filter(Boolean);
const pids = new Set();
for (const line of lines) {
const parts = line.trim().split(/\s+/);
const localAddress = parts[1] || '';
if (localAddress.includes(`:${port}`)) {
const pid = parts[4] || parts[3];
if (pid && pid !== '0' && /^\d+$/.test(pid)) {
pids.add(pid);
}
}
}
return [...pids];
} catch {
return [];
}
}
async function killProcess(pid) {
return new Promise((resolve) => {
exec(`taskkill /F /PID ${pid}`, (err, stdout) => {
resolve({ pid, success: !err, output: stdout });
});
});
}
async function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function checkAndKillPorts() {
console.log('🔍 检查端口占用情况...\n');
for (const { port, name } of PORTS) {
const pids = await getProcessesUsingPort(port);
if (pids.length > 0) {
console.log(`⚠️ ${name} 端口 ${port} 被占用 (PID: ${pids.join(', ')}), 正在清理...`);
for (const pid of pids) {
await killProcess(pid);
}
await sleep(500); // 等待进程完全退出
console.log(`✅ 端口 ${port} 已清理\n`);
} else {
console.log(`✅ 端口 ${port} 空闲`);
}
}
console.log('\n🚀 启动服务...\n');
}
const command = process.argv[2];
const args = process.argv.slice(3);
checkAndKillPorts().then(() => {
if (command) {
const child = spawn(command, args, {
stdio: 'inherit',
shell: true,
});
child.on('error', (err) => {
console.error('启动失败:', err);
process.exit(1);
});
child.on('close', (code) => {
process.exit(code || 0);
});
} else {
console.log('用法: node scripts/check-ports.js <command> [args...]');
process.exit(0);
}
});