Comandos Linux que todo dev precisa saber

1. Visão geral

Todo dev já SSH’ed em um servidor, abriu um terminal para debugar ou fazer deploy de uma app, e depois ficou procurando o comando correto. Este artigo reúne os comandos Linux mais usados no dia a dia: gerenciar arquivos, buscar, processar texto, monitorar processos, verificar rede, visualizar logs. Depois de ler, você terá um arsenal de comandos “essenciais” para debugar rapidamente sem precisar googlar de novo a cada vez.

Vou usar bash no Ubuntu/Debian como exemplo principal — esses comandos são praticamente iguais em todas as distros.

2. Operações básicas com arquivos e diretórios

mkdir -p ~/projects/order-service/src/main/java
cd ~/projects/order-service
touch application.properties
ls -la
  • mkdir -p cria toda a árvore de diretórios, sem erro se o diretório já existe.
  • touch cria um arquivo vazio (ou atualiza o timestamp se já existe).
  • ls -la lista todos os arquivos (incluindo ocultos .env, .git) com permissões, owner, tamanho.
drwxr-xr-x  3 nonla nonla 4096 Oct  5 10:00 .
-rw-r--r--  1 nonla nonla    0 Oct  5 10:00 application.properties

Alguns comandos de movimentação/remoção precisam de cuidado:

cp -r src/ src-backup/     # copia diretório recursivamente
mv OrderService.java OrderServiceImpl.java   # renomeia ou move
rm -rf target/            # remove recursivamente, sem pergunta

Aviso: rm -rf não tem lixeira, deletado é deletado. Sempre verifique o caminho com pwd antes de rodar, especialmente ao copiar-colar comandos de outros lugares.

3. Buscando com find e grep

3.1. find — encontra arquivos por condição

find . -name "*.java" -newer pom.xml

Este comando encontra todos os arquivos .java modificados depois de pom.xml — útil quando quer saber qual arquivo foi alterado antes de fazer commit.

find . -type f -size +10M

Encontra arquivos maiores que 10MB, comum para limpar logs ou build artifacts que ocupam espaço.

3.2. grep — encontra conteúdo dentro de arquivos

grep -rn "PaymentService" --include="*.java" src/
  • -r busca recursivamente em subdiretórios.
  • -n imprime com número da linha.
  • --include limita só arquivos .java, evitando vasculhar target/.
src/main/java/com/nonla/OrderController.java:15:    private final PaymentService paymentService;

Combine grep com find via pipe quando precisa de filtro mais complexo:

find . -name "*.log" | xargs grep -l "OutOfMemoryError"

xargs passa a lista de arquivos de find para grep -l (só imprime nome do arquivo que contém o pattern, não o conteúdo).

4. Processando texto com awk, sed, cut

Este é o grupo de comandos “devoradores de logs” — extremamente poderosos quando você precisa extrair dados de saída longa.

cat access.log | awk '{print $1}' | sort | uniq -c | sort -rn | head -5
  • awk '{print $1}' pega a primeira coluna (geralmente IP) de cada linha do log.
  • sort | uniq -c agrupa e conta quantas vezes aparecem.
  • sort -rn ordena decrescente por número, head -5 pega top 5.
    152 192.168.1.10
     98 10.0.0.5
     47 172.16.0.3

Esta é a forma mais rápida de encontrar qual IP faz mais requisições sem precisar escrever um script.

sed é usado para substituir texto diretamente em um arquivo:

sed -i 's/spring.profiles.active=dev/spring.profiles.active=prod/' application.properties

-i modifica o arquivo no local (in-place). Se quiser mais segurança, use sed -i.bak '...' para criar arquivo backup .bak automaticamente.

cut separa colunas por delimitador, mais leve que awk quando você só precisa de uma coluna simples:

cat /etc/passwd | cut -d: -f1 | head -3

5. Monitorando processos e recursos do sistema

ps aux | grep java

Imprime todos os processos, filtra linha contendo java — forma rápida de ver se sua app Spring Boot está rodando e qual é o PID.

nonla    12345  2.1  5.3 2345678 432100 ?      Sl   10:00   0:15 java -jar order-service.jar

A segunda coluna é o PID. Use este PID para matar ou ver detalhes:

kill -15 12345     # envia SIGTERM, deixa a app fazer graceful shutdown
kill -9 12345       # força matar, use só quando -15 não funciona

Aviso: kill -9 não deixa a app rodar shutdown hooks (como fechar connection pool, flush logs). Sempre tente -15 primeiro.

Veja recursos em tempo real:

top -o %MEM

-o %MEM ordena processos por RAM mais usada — útil quando suspeita de memory leak. Se quiser interface mais bonita, instale htop.

Verifica disco:

df -h
du -sh /var/log/*

df -h vê espaço em cada partição (legível por humanos). du -sh vê quanto cada subdiretório em /var/log ocupa — muito necessário quando o servidor avisa “no space left on device”.

6. Verificando rede e portas

ss -tulnp | grep 8080
  • ss substitui o antigo netstat, mais rápido.
  • -t TCP, -u UDP, -l listening, -n numérico (sem resolver DNS), -p com processo.
tcp   LISTEN  0  128  0.0.0.0:8080  0.0.0.0:*  users:(("java",pid=12345,fd=45))

Descobre imediatamente que a porta 8080 está sendo usada pelo processo Java PID 12345 — muito útil ao encontrar erro Address already in use.

Teste uma API rapidamente com curl:

curl -s -X POST http://localhost:8080/api/orders \
  -H "Content-Type: application/json" \
  -d '{"customerId":1,"amount":99.5}'

-s silencioso (esconde a barra de progresso), -X POST escolhe o método, -d corpo JSON. Adicione -i se quiser ver headers da resposta também.

O comando lsof é útil quando precisa saber exatamente qual arquivo/socket um processo está abrindo:

lsof -i :8080

7. Permissões de arquivos

chmod +x deploy.sh
chown nonla:nonla application.properties
chmod 640 .env
  • chmod +x dá permissão de execução para o script.
  • chown user:group muda o proprietário — geralmente precisa sudo quando o arquivo pertence a outro usuário.
  • chmod 640 significa owner lê/escreve (6), grupo só lê (4), outros sem permissão (0) — padrão para arquivos secretos como .env.
-rw-r----- 1 nonla nonla 128 Oct  5 10:00 .env

Aviso: nunca faça chmod 777 em produção. É a forma mais rápida de todo usuário na máquina poder ler/editar seus arquivos sensíveis.

8. Compactando e descompactando

tar -czvf order-service.tar.gz order-service/
tar -xzvf order-service.tar.gz -C /opt/apps/
  • -c cria arquivo, -x descompacta, -z usa gzip, -v verbose, -f especifica nome do arquivo.
  • -C ao descompactar especifica diretório destino em vez de descompactar no diretório atual.

Ao fazer deploy, combine com scp ou rsync para mandar arquivo para o servidor:

scp order-service.tar.gz user@10.0.0.5:/opt/apps/
rsync -avz --progress target/*.jar user@10.0.0.5:/opt/apps/

rsync só transfere partes de dados que mudaram (delta transfer), muito mais rápido que scp quando atualiza arquivo grande várias vezes.

9. Visualizando logs em tempo real

tail -f /var/log/order-service/app.log

-f (follow) mantém o terminal aberto e imprime novas linhas assim que o arquivo é escrito — comando obrigatório ao debugar produção.

Filtre log por pattern ao fazer tail:

tail -f app.log | grep --line-buffered "ERROR"

--line-buffered é necessário porque grep por padrão bufferiza por bloco, sem essa flag a saída pode atrasar ao fazer pipe com tail -f.

Se a app roda sob systemd, use journalctl em vez de procurar arquivo de log manualmente:

journalctl -u order-service -f --since "10 minutes ago"

-u especifica a unidade de serviço, -f segue, --since limita o tempo — evita ter que ler milhões de linhas de log antigo.

10. Rodando comandos Linux do Java

Às vezes você precisa chamar comando shell direto do código Java, por exemplo verificar espaço em disco antes de escrever um arquivo grande:

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.List;

public class ShellRunner {

    public static String run(List<String> command) throws Exception {
        ProcessBuilder builder = new ProcessBuilder(command);
        builder.redirectErrorStream(true);
        Process process = builder.start();

        try (BufferedReader reader =
                new BufferedReader(new InputStreamReader(process.getInputStream()))) {
            String output = reader.lines().reduce("", (a, b) -> a + b + "\n");
            process.waitFor();
            return output;
        }
    }
}
  • ProcessBuilder recebe lista de argumentos (não é uma string de comando colada, evita shell injection).
  • redirectErrorStream(true) mescla stderr com stdout para ler um fluxo único.
  • process.waitFor() bloqueia a thread atual até que o processo filho termine.

Teste com JUnit 5 + AssertJ:

import org.junit.jupiter.api.Test;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;

class ShellRunnerTest {

    @Test
    void shouldReturnCurrentDirectoryListing() throws Exception {
        String output = ShellRunner.run(List.of("ls", "-la"));

        assertThat(output).contains("total");
    }
}

Este teste roda ls -la de verdade no sistema e verifica se a saída contém total (primeira linha que ls -la sempre imprime com o total de blocos) — confirma que ProcessBuilder realmente consegue chamar comando shell.

Aviso: chamar comando shell do código Java em produção é uma faca de dois gumes — fácil depender do SO, difícil de testar, e risco de injection se o argumento vem de entrada de usuário. Use só para ferramentas internas ou scripts de operação, evite para lógica de negócio principal.

11. Erros comuns

  • Rodar rm -rf com variável de ambiente vazia, como rm -rf $DIR/* quando $DIR não foi definida — deleta acidentalmente diretório raiz. Sempre use set -u em script ou verifique variável antes.
  • Esquecer sudo quando precisa de permissão root, resultando em erro vago Permission denied — verifique com ls -la antes de culpar a app.
  • Usar kill -9 por hábito, deixando app Spring Boot sem tempo de fechar connection pool, causando leak no banco de dados.
  • Fazer pipe grep após tail -f e esquecer --line-buffered, achando que o log não está rodando quando na verdade está bufferizado.
  • Rodar chmod 777 para “passar rápido pelo erro de permissão” — cria buracos de segurança, especialmente perigoso com arquivo .env ou chave SSH.

12. Conclusão

Os comandos neste artigo — find, grep, awk/sed, ps/kill, ss/curl, tar, tail -f, journalctl — formam o arsenal mínimo para você debugar sozinho sem precisar esperar o time DevOps. Dominar tudo não significa memorizar todas as flags, só conhecer qual comando resolve qual problema e consultar man quando precisa de detalhe. O terminal ainda é a ferramenta de debug mais rápida, mesmo que você tenha Grafana, Kibana ou ferramentas APM ao redor.

linuxdevopsbashproductivityjava