Skip to content

Instantly share code, notes, and snippets.

@dansp89
Created July 5, 2026 15:58
Show Gist options
  • Select an option

  • Save dansp89/920fe56c293a52405680a03eac683cc0 to your computer and use it in GitHub Desktop.

Select an option

Save dansp89/920fe56c293a52405680a03eac683cc0 to your computer and use it in GitHub Desktop.
c: fecha portas TCP (cross-platform)
<#
c — fecha uma ou mais portas TCP (mata os processos) e espera cada uma ficar livre.
Uso: c <porta1> [porta2] [portaN...]
Timeout interno: 10s por porta.
#>
param([Parameter(ValueFromRemainingArguments = $true)] [string[]] $Portas)
if (-not $Portas -or $Portas.Count -eq 0) {
Write-Host "Uso: c <porta1> [porta2] [portaN...]"
exit 1
}
$timeout = 10
$rc = 0
foreach ($porta in $Portas) {
if ($porta -notmatch '^\d+$') { Write-Warning "Ignorando '$porta' (nao e porta)"; continue }
Write-Host "Aguardando porta $porta fechar..."
$inicio = Get-Date
while ($true) {
$procIds = @()
try {
$procIds = Get-NetTCPConnection -LocalPort $porta -ErrorAction Stop |
Select-Object -ExpandProperty OwningProcess -Unique
} catch {
# Fallback via netstat (ambientes sem o modulo NetTCPIP)
$procIds = @(netstat -ano | Select-String ":$porta\s" |
ForEach-Object { ($_ -split '\s+')[-1] } | Sort-Object -Unique)
}
$procIds = $procIds | Where-Object { $_ -and $_ -ne 0 }
if (-not $procIds) { Write-Host "OK: porta $porta fechada!"; break }
foreach ($p in $procIds) { Stop-Process -Id $p -Force -ErrorAction SilentlyContinue }
if (((Get-Date) - $inicio).TotalSeconds -ge $timeout) {
Write-Warning "Timeout: porta $porta ainda ocupada apos ${timeout}s"
$rc = 1
break
}
Start-Sleep -Milliseconds 200
}
}
exit $rc
# c: fecha uma ou mais portas TCP e espera ficarem livres.
# Uso: c <porta1> [porta2] [portaN...] (timeout interno: 10s por porta)
c() {
if [ $# -eq 0 ]; then
echo "Uso: c <porta1> [porta2] [portaN...]"
return 1
fi
local timeout=10 rc=0
for porta in "$@"; do
case "$porta" in
''|*[!0-9]*) echo "Ignorando '$porta' (nao e porta)"; continue ;;
esac
echo "Aguardando porta $porta fechar..."
local inicio=$(date +%s)
while true; do
local pids=""
if command -v lsof >/dev/null 2>&1; then
pids=$(lsof -ti :"$porta" 2>/dev/null)
else
pids=$(netstat -ano 2>/dev/null | awk -v p=":$porta$" '$2 ~ p {print $NF}' | sort -u)
fi
if [ -z "$pids" ]; then
echo "OK: porta $porta fechada!"
break
fi
for pid in $pids; do
[ "$pid" = "0" ] && continue
if command -v taskkill >/dev/null 2>&1; then
MSYS_NO_PATHCONV=1 taskkill /F /PID "$pid" >/dev/null 2>&1
else
kill -9 "$pid" 2>/dev/null
fi
done
if [ $(( $(date +%s) - inicio )) -ge $timeout ]; then
echo "Timeout: porta $porta ainda ocupada apos ${timeout}s"
rc=1
break
fi
sleep 0.2
done
done
return $rc
}
# Instalador do comando `c` para Windows PowerShell.
# irm https://gist.githubusercontent.com/<voce>/<id>/raw/install.ps1 | iex
# Idempotente. Instala o engine em ~\.local\bin, wrapper CMD e função no perfil.
$ErrorActionPreference = 'Stop'
$bin = Join-Path $HOME '.local\bin'
New-Item -ItemType Directory -Path $bin -Force | Out-Null
# ── Engine c.ps1 ──────────────────────────────────────────────────────────────
$engine = @'
param([Parameter(ValueFromRemainingArguments = $true)] [string[]] $Portas)
if (-not $Portas -or $Portas.Count -eq 0) { Write-Host "Uso: c <porta1> [porta2] [portaN...]"; exit 1 }
$timeout = 10; $rc = 0
foreach ($porta in $Portas) {
if ($porta -notmatch '^\d+$') { Write-Warning "Ignorando '$porta' (nao e porta)"; continue }
Write-Host "Aguardando porta $porta fechar..."
$inicio = Get-Date
while ($true) {
$procIds = @()
try {
$procIds = Get-NetTCPConnection -LocalPort $porta -ErrorAction Stop |
Select-Object -ExpandProperty OwningProcess -Unique
} catch {
$procIds = @(netstat -ano | Select-String ":$porta\s" |
ForEach-Object { ($_ -split '\s+')[-1] } | Sort-Object -Unique)
}
$procIds = $procIds | Where-Object { $_ -and $_ -ne 0 }
if (-not $procIds) { Write-Host "OK: porta $porta fechada!"; break }
foreach ($p in $procIds) { Stop-Process -Id $p -Force -ErrorAction SilentlyContinue }
if (((Get-Date) - $inicio).TotalSeconds -ge $timeout) {
Write-Warning "Timeout: porta $porta ainda ocupada apos ${timeout}s"; $rc = 1; break
}
Start-Sleep -Milliseconds 200
}
}
exit $rc
'@
Set-Content -Path (Join-Path $bin 'c.ps1') -Value $engine -Encoding utf8
Write-Host " -> $bin\c.ps1"
# ── Wrapper CMD (ASCII puro, sem <> nos comentarios) ─────────────────────────
$cmd = "@echo off`r`nrem c - fecha portas TCP e espera ficarem livres.`r`npowershell -NoProfile -ExecutionPolicy RemoteSigned -File `"%~dp0c.ps1`" %*`r`n"
Set-Content -Path (Join-Path $bin 'c.cmd') -Value $cmd -Encoding ascii -NoNewline
Write-Host " -> $bin\c.cmd"
# ── PATH do usuario (para o CMD achar c.cmd) ─────────────────────────────────
$userPath = [Environment]::GetEnvironmentVariable('Path', 'User')
if (($userPath -split ';') -notcontains $bin) {
[Environment]::SetEnvironmentVariable('Path', ($userPath.TrimEnd(';') + ';' + $bin), 'User')
Write-Host " -> adicionado ao PATH do usuario: $bin"
}
# ── Funcao no perfil do PowerShell (idempotente) ─────────────────────────────
$profileDir = Split-Path $PROFILE.CurrentUserAllHosts
if (-not (Test-Path $profileDir)) { New-Item -ItemType Directory -Path $profileDir -Force | Out-Null }
$profilePath = $PROFILE.CurrentUserAllHosts
$jaTem = (Test-Path $profilePath) -and (Select-String -Path $profilePath -Pattern 'function c ' -Quiet)
if (-not $jaTem) {
Add-Content -Path $profilePath -Value "`n# c-killport`nfunction c { & `"`$HOME\.local\bin\c.ps1`" @args }" -Encoding utf8
Write-Host " -> funcao adicionada em $profilePath"
}
Write-Host ""
Write-Host "Pronto! Abra um novo terminal (ou rode: . `$PROFILE)."
Write-Host "Uso: c 3000 8080 8473"
#!/usr/bin/env bash
# Instalador do comando `c` (fecha portas TCP e espera ficarem livres).
# curl -fsSL https://gist.githubusercontent.com/<voce>/<id>/raw/install.sh | bash
# Idempotente e cross-platform (Linux, macOS, Git Bash).
set -e
SHARE="$HOME/.local/share/c-killport"
BIN="$HOME/.local/bin"
mkdir -p "$SHARE" "$BIN"
MARKER="# >>> c-killport (source) >>>"
# ── Grava a função bash (heredoc single-quoted = sem escaping) ────────────────
cat > "$SHARE/c.sh" <<'CSH_EOF'
# c: fecha uma ou mais portas TCP e espera ficarem livres.
# Uso: c <porta1> [porta2] [portaN...] (timeout interno: 10s por porta)
c() {
if [ $# -eq 0 ]; then
echo "Uso: c <porta1> [porta2] [portaN...]"
return 1
fi
local timeout=10 rc=0
for porta in "$@"; do
case "$porta" in
''|*[!0-9]*) echo "Ignorando '$porta' (nao e porta)"; continue ;;
esac
echo "Aguardando porta $porta fechar..."
local inicio=$(date +%s)
while true; do
local pids=""
if command -v lsof >/dev/null 2>&1; then
pids=$(lsof -ti :"$porta" 2>/dev/null)
else
pids=$(netstat -ano 2>/dev/null | awk -v p=":$porta$" '$2 ~ p {print $NF}' | sort -u)
fi
if [ -z "$pids" ]; then
echo "OK: porta $porta fechada!"
break
fi
for pid in $pids; do
[ "$pid" = "0" ] && continue
if command -v taskkill >/dev/null 2>&1; then
MSYS_NO_PATHCONV=1 taskkill /F /PID "$pid" >/dev/null 2>&1
else
kill -9 "$pid" 2>/dev/null
fi
done
if [ $(( $(date +%s) - inicio )) -ge $timeout ]; then
echo "Timeout: porta $porta ainda ocupada apos ${timeout}s"
rc=1
break
fi
sleep 0.2
done
done
return $rc
}
CSH_EOF
# ── Adiciona 'source' aos rc files (guardado por marcador, idempotente) ───────
add_source() {
local rc="$1"
[ -f "$rc" ] || touch "$rc"
grep -qF "$MARKER" "$rc" && return 0
{
echo ""
echo "$MARKER"
echo "[ -f \"$SHARE/c.sh\" ] && . \"$SHARE/c.sh\""
echo "# <<< c-killport (source) <<<"
} >> "$rc"
echo " -> $rc"
}
echo "Instalando comando 'c'..."
add_source "$HOME/.bashrc"
[ -f "$HOME/.zshrc" ] && add_source "$HOME/.zshrc"
# ── Bônus no Windows/Git Bash: instala tambem para PowerShell e CMD ──────────
case "$(uname -s)" in
MINGW*|MSYS*|CYGWIN*)
echo "Windows detectado — instalando também para PowerShell e CMD..."
# engine c.ps1
curl -fsSL "https://gist.githubusercontent.com/REPLACE_ME/raw/c.ps1" -o "$BIN/c.ps1" 2>/dev/null || true
# wrapper c.cmd
printf '@echo off\r\nrem c - fecha portas TCP e espera ficarem livres.\r\npowershell -NoProfile -ExecutionPolicy RemoteSigned -File "%%~dp0c.ps1" %%*\r\n' > "$BIN/c.cmd"
echo " -> $BIN/c.cmd (garanta que $BIN esta no PATH)"
;;
esac
echo ""
echo "Pronto! Abra um novo terminal ou rode: source ~/.bashrc"
echo "Uso: c 3000 8080 8473"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment