PowerShell para quem vem do Bash: equivalências práticas
1. Paradigmas e Filosofia de Comando
A diferença fundamental entre PowerShell e Bash está na natureza dos dados que fluem pelo pipeline. Enquanto o Bash manipula texto puro, o PowerShell trabalha com objetos .NET. Isso significa que, no Bash, você extrai informações de saídas textuais com grep, awk e sed; no PowerShell, você acessa propriedades diretamente.
Cmdlets vs. comandos Unix: PowerShell adota a estrutura Verbo-Substantivo. O comando ps do Unix equivale a Get-Process. A vantagem é que Get-Process retorna objetos com propriedades como Name, Id, CPU, que você pode acessar com pontos:
# Bash
ps aux | grep firefox
# PowerShell
Get-Process -Name firefox | Select-Object Name, CPU
Aliases e atalhos: PowerShell fornece aliases para facilitar a transição. ls, cat, rm, cp, mv funcionam, mas com comportamento sutilmente diferente. Por exemplo, ls no PowerShell é alias para Get-ChildItem e aceita parâmetros como -Recurse e -Filter.
2. Navegação e Manipulação de Arquivos
Listar diretórios: Get-ChildItem (alias ls, dir) oferece filtragem avançada:
# Bash: ls -la *.txt
# PowerShell:
Get-ChildItem -Filter *.txt | Format-Table Name, Length, LastWriteTime
Criar, copiar, mover e remover: Os cmdlets seguem o padrão Verbo-Item:
# Criar diretório
New-Item -ItemType Directory -Path C:\Temp\projeto
# Copiar arquivo
Copy-Item -Path arquivo.txt -Destination backup\ -Recurse
# Mover e renomear
Move-Item -Path relatorio.csv -Destination arquivos\relatorio_2024.csv
# Remover com confirmação
Remove-Item -Path temp\* -Recurse -Confirm
Caminhos e diretórios: Get-Location (pwd), Set-Location (cd), Split-Path (dirname):
# Bash: pwd; cd /var/log; dirname /var/log/syslog
# PowerShell:
Get-Location
Set-Location C:\Windows\System32
Split-Path -Parent "C:\Windows\System32\notepad.exe"
3. Filtragem, Seleção e Ordenação
Where-Object substitui grep e awk no pipeline de objetos:
# Bash: ps aux | grep chrome
# PowerShell:
Get-Process | Where-Object { $_.ProcessName -like "*chrome*" }
# Filtro por condição composta
Get-Process | Where-Object { $_.CPU -gt 10 -and $_.WorkingSet -gt 100MB }
Select-Object equivale a cut e awk '{print $1}':
# Bash: ps aux | awk '{print $2, $11}'
# PowerShell:
Get-Process | Select-Object Id, ProcessName, @{Name="Memória(MB)"; Expression={[math]::Round($_.WorkingSet/1MB,2)}}
Sort-Object substitui sort e uniq:
# Ordenar por uso de CPU (decrescente)
Get-Process | Sort-Object CPU -Descending | Select-Object -First 5
# Agrupar e contar (uniq -c)
Get-Service | Group-Object Status | Select-Object Name, Count
4. Trabalhando com Texto e Strings
Operadores de comparação: -match (regex), -like (curinga), -contains (coleções):
# Bash: grep "^ERROR" log.txt
# PowerShell:
Get-Content log.txt | Where-Object { $_ -match "^ERROR" }
# Verificar se string contém padrão
if ("arquivo.txt" -like "*.txt") { Write-Output "É um arquivo texto" }
Substituição e formatação: -replace (regex), -split, -join:
# Bash: sed 's/antigo/novo/g' arquivo.txt
# PowerShell:
(Get-Content arquivo.txt) -replace "antigo", "novo" | Set-Content arquivo.txt
# Dividir string e unir com delimitador personalizado
$linha = "nome,idade,cidade"
$partes = $linha -split ","
$partes -join " | "
Leitura e escrita em arquivos: Get-Content, Set-Content, Add-Content:
# Bash: cat arquivo.txt; echo "linha" > arquivo.txt; echo "linha" >> arquivo.txt
# PowerShell:
Get-Content arquivo.txt
"texto" | Set-Content arquivo.txt # sobrescreve
"texto" | Add-Content arquivo.txt # anexa
5. Estruturas de Controle e Scripting
Condicionais e loops: sintaxe similar a linguagens C-like:
# Bash: for i in ${array[@]}; do echo $i; done
# PowerShell:
$servidores = @("web01", "db01", "app01")
foreach ($servidor in $servidores) {
if (Test-Connection -ComputerName $servidor -Count 1 -Quiet) {
Write-Output "$servidor está online"
} else {
Write-Warning "$servidor offline"
}
}
Funções e escopo: uso de param() para parâmetros tipados:
function Get-DiskUsage {
param(
[Parameter(Mandatory=$true)]
[string]$Caminho,
[ValidateSet("KB","MB","GB")]
[string]$Unidade = "MB"
)
$itens = Get-ChildItem -Path $Caminho -Recurse -File
$total = ($itens | Measure-Object -Property Length -Sum).Sum
switch ($Unidade) {
"KB" { $total / 1KB }
"MB" { $total / 1MB }
"GB" { $total / 1GB }
}
}
Tratamento de erros: try/catch/finally substitui set -e e ||:
try {
Get-Content "caminho\inexistente.txt" -ErrorAction Stop
} catch [System.IO.FileNotFoundException] {
Write-Error "Arquivo não encontrado: $_"
} catch {
Write-Error "Erro desconhecido: $_"
} finally {
Write-Output "Execução concluída"
}
6. Gerenciamento de Processos e Serviços
Listar e encerrar processos: cmdlets nativos com objetos:
# Bash: ps aux --sort=-%mem | head -5; kill -9 1234
# PowerShell:
Get-Process | Sort-Object WorkingSet -Descending | Select-Object -First 5
Stop-Process -Name notepad -Force
Gerenciar serviços: Get-Service, Start-Service, Restart-Service:
# Bash: systemctl status nginx; systemctl restart nginx
# PowerShell:
Get-Service -Name Spooler | Select-Object Name, Status, StartType
Restart-Service -Name Spooler -PassThru
Monitoramento e logs: Get-EventLog (logs clássicos) e Get-WinEvent (logs modernos):
# Bash: journalctl -u sshd --since "1 hour ago"
# PowerShell:
Get-WinEvent -LogName System -MaxEvents 10 | Where-Object { $_.LevelDisplayName -eq "Error" }
7. Automação com Pipeline e Expressões
Pipeline avançado: encadeamento de cmdlets com ForEach-Object:
Get-Service | Where-Object Status -eq "Stopped" | ForEach-Object {
Write-Output "Iniciando serviço: $($_.DisplayName)"
Start-Service -Name $_.Name
}
Expressões calculadas: criar propriedades customizadas com @{Name=; Expression=}:
Get-Process | Select-Object Name, Id, @{
Name = "Memória(MB)"
Expression = { [math]::Round($_.WorkingSet/1MB, 2) }
}, @{
Name = "Tempo(Minutos)"
Expression = { [math]::Round($_.TotalProcessorTime.TotalMinutes, 2) }
}
Exportação de dados: Export-Csv, ConvertTo-Json, Out-File:
# Exportar processos para CSV
Get-Process | Select-Object Name, CPU, WorkingSet | Export-Csv -Path processos.csv -NoTypeInformation
# Converter para JSON
Get-Service | Where-Object Status -eq "Running" | ConvertTo-Json | Out-File servicos.json
# Formatar saída em tabela
Get-Process | Format-Table -AutoSize -Wrap
Referências
- Documentação oficial do PowerShell — Guia completo de cmdlets, sintaxe e exemplos práticos
- PowerShell for Unix users — Documentação da Microsoft comparando comandos Unix com PowerShell
- PowerShell vs Bash: principais diferenças — Artigo da Red Hat sobre paradigmas e casos de uso
- PowerShell One-Liners para administradores — Coleção de comandos práticos para automação de tarefas
- Cheat Sheet: Bash to PowerShell — Tabela de equivalências entre comandos Bash e PowerShell
- PowerShell em 30 dias — Repositório com exercícios interativos para aprender PowerShell gradualmente