fix(cli): replace platform-specific netstat/ss commands with lsof for unified port usage checks.

This commit is contained in:
melvinchia3636
2026-02-04 22:51:49 +08:00
parent 1e3827f455
commit 8cd4010a8c

View File

@@ -139,80 +139,30 @@ export function checkAddressInUse(address: string, port: string): boolean {
try {
executeCommand('nc', { exitOnError: false }, ['-zv', address, port])
const isMacOS = process.platform === 'darwin'
const lsofOutput = executeCommand('lsof', { exitOnError: false }, [
'-i',
`@${address}:${port}`,
'-sTCP:LISTEN'
])
if (isMacOS) {
const netstatOutput = executeCommand('netstat', { exitOnError: false }, [
'-anv',
'-p',
'tcp'
])
const lines = lsofOutput.trim().split('\n')
const lines = netstatOutput.trim().split('\n')
const dataLine = lines.find(line => !line.startsWith('COMMAND'))
const matchingLine = lines.find(
line =>
line.includes(`${address}.${port}`) ||
line.includes(`*.${port}`) ||
(address === 'localhost' && line.includes(`127.0.0.1.${port}`)) ||
(address === '127.0.0.1' && line.includes(`localhost.${port}`))
if (dataLine) {
const parts = dataLine.trim().split(/\s+/)
const processName = parts[0]
const pid = parts[1]
logger.error(
`Address ${chalk.blue(address)}:${chalk.blue(port)} is in use by process: ${chalk.blue(processName)} (PID: ${chalk.blue(pid)})`
)
if (matchingLine) {
const parts = matchingLine.trim().split(/\s+/)
const processInfo = parts.find(part => /^.+:\d+$/.test(part))
if (processInfo) {
const [processName, pid] = processInfo.split(':')
logger.error(
`Address ${chalk.blue(address)}:${chalk.blue(port)} is in use by process: ${chalk.blue(processName)} (PID: ${chalk.blue(pid)})`
)
} else {
logger.error(
`Address ${chalk.blue(address)}:${chalk.blue(port)} is in use, but could not parse process info.`
)
}
} else {
logger.error(
`Address ${chalk.blue(address)}:${chalk.blue(port)} is in use, but no process info found.`
)
}
} else {
const ssOutput = executeCommand('ss', { exitOnError: false }, [
'-tlnp',
'src',
`${address}:${port}`
])
const lines = ssOutput.trim().split('\n')
if (lines.length > 1) {
const processLine = lines[1]
const processMatch = processLine.match(
/users:\(\("([^"]+)",pid=(\d+),fd=\d+\)\)/
)
if (processMatch) {
const processName = processMatch[1]
const pid = processMatch[2]
logger.error(
`Address ${chalk.blue(address)}:${chalk.blue(port)} is in use by process: ${chalk.blue(processName)} (PID: ${chalk.blue(pid)})`
)
} else {
logger.error(
`Address ${chalk.blue(address)}:${chalk.blue(port)} is in use, but could not parse process info.`
)
}
} else {
logger.error(
`Address ${chalk.blue(address)}:${chalk.blue(port)} is in use, but no process info found.`
)
}
logger.error(
`Address ${chalk.blue(address)}:${chalk.blue(port)} is in use, but no process info found.`
)
}
return true