Objetivos de Aprendizagem
Ao final deste módulo, o aluno será capaz de:
- Explicar o papel do kernel e a diferença entre kernel space e user space
- Descrever o ciclo de uma chamada de sistema (syscall)
- Identificar as principais distribuições Linux e suas diferenças
- Navegar pela hierarquia de diretórios FHS com fluência
- Usar o shell Bash para executar comandos essenciais
- Entender o que é um processo e como o kernel o gerencia
- Ler e interpretar as páginas de manual (
man) - Executar os dois laboratórios guiados com autonomia
Pré-Requisitos
Conhecimentos prévios
- Noções básicas de computação (o que é CPU, memória, disco)
- Experiência mínima com qualquer sistema operacional (Windows / macOS)
- Conceito de arquivo e pasta/diretório
Ambiente necessário
- VM com Ubuntu 22.04 LTS ou Debian 12 instalada
- Acesso a um terminal (TTY ou emulador)
- Usuário não-root criado e senha definida
- Conexão com a internet (opcional, para
apt)
- Não funciona:
modprobe(o container não carrega módulos),ls -l /dev/sdaefdisk -l(não há discos),dmesg(Operation not permitted). - Cuidado ao interpretar:
lsmodlista os módulos do host, em modo leitura — não são "do seu sistema".lsblkmostra apenas umsr0fantasma. - Instalar antes:
sudo apt install build-essential— necessário para compilar ole_arquivo.cdo Bloco 2. - Funciona normalmente:
/proc,strace,uname,man/apropos,ps, pipes, redirecionamentos e os dois laboratórios.
Conceitos-chave
Um Sistema Operacional (SO) é o software que atua como intermediário entre o hardware e os programas do usuário. Ele fornece abstrações (arquivos, processos, sockets) e garante isolamento, segurança e compartilhamento de recursos entre múltiplos programas simultâneos.
Segundo a LPI (Linux Essentials, Topic 4 — The Linux Operating System), o termo "Linux" refere-se tecnicamente apenas ao kernel. O que instalamos e usamos no dia a dia é uma distribuição: o kernel Linux somado a milhares de programas do projeto GNU, bibliotecas, um sistema de init, um gerenciador de pacotes e utilitários. Por isso a Free Software Foundation defende o nome GNU/Linux para o sistema completo.
As duas grandes responsabilidades do kernel
Todo SO existe para resolver dois problemas fundamentais que aparecem quando vários programas disputam um mesmo computador:
- Abstração — transformar hardware complicado e heterogêneo em interfaces simples e uniformes. O programa lê um "arquivo" sem saber se ele está num SSD NVMe, num HD SATA ou num pen-drive USB; abre um "socket" sem conhecer o driver da placa de rede.
- Arbitragem — decidir quem usa a CPU, a memória e os dispositivos, quando e por quanto tempo, impedindo que um programa interfira nos outros (isolamento) ou monopolize os recursos (escalonamento justo).
Abstrações fundamentais oferecidas pelo SO
O princípio "tudo é um arquivo"
Uma das ideias centrais herdadas do Unix é que a maioria dos recursos é exposta como
arquivos, manipuláveis com as mesmas syscalls (open, read,
write, close). Isso dá uma coerência enorme ao sistema:
# Um terminal é um arquivo — escrever nele mostra texto na tela de outro TTY $ tty /dev/pts/0 $ echo "olá" > /dev/pts/0 # aparece no próprio terminal # Um disco é um arquivo de bloco $ ls -l /dev/sda brw-rw---- 1 root disk 8, 0 Jul 20 10:00 /dev/sda # /dev/null descarta tudo; /dev/zero produz zeros infinitos $ echo "isto some" > /dev/null $ head -c 8 /dev/zero | xxd 00000000: 0000 0000 0000 0000 ........
Multitarefa e multiusuário
Diferente de sistemas antigos, o Linux é multitarefa preemptiva (o kernel pode interromper um processo a qualquer momento para dar a vez a outro) e multiusuário (vários usuários com identidades e permissões distintas podem trabalhar simultaneamente). O escalonador (scheduler) cria a ilusão de que tudo roda ao mesmo tempo, alternando processos na CPU em fatias de milissegundos.
Monolítico vs. microkernel
O Linux é um kernel monolítico modular: drivers, sistema de arquivos e pilha de rede rodam todos em kernel space (desempenho alto), mas podem ser carregados e descarregados em tempo real como módulos. Isso o diferencia de microkernels (como o Minix), que mantêm o mínimo em kernel space e empurram serviços para user space (maior isolamento, menor desempenho).
$ lsmod | head -5 # módulos carregados Module Size Used by ext4 980992 1 xhci_pci 24576 0 snd_hda_intel 57344 3 $ modinfo ext4 | head -3 # metadados de um módulo # modprobe -r módulo # descarrega (necessita root)
Linha do tempo do Linux
# Marcos históricos relevantes
1969 → Unix (Bell Labs — Thompson, Ritchie)
1983 → Projeto GNU (Richard Stallman)
1991 → Linux Kernel 0.01 (Linus Torvalds)
1992 → GPL + GNU + Linux = GNU/Linux
1993 → Slackware (1ª distro popular)
1994 → Red Hat Linux
2004 → Ubuntu (Canonical)
Hoje → +600 distribuições ativas
Arquitetura em camadas
Aplicações: bash, vim, Python, nginx, Firefox…
Bibliotecas: glibc, libpthread…
(open, read, write, fork, exec, mmap…)
Scheduler · Memory Manager · VFS · Drivers · Network Stack
Modos de operação da CPU
A separação entre kernel e aplicações não é apenas uma convenção de software: ela é imposta pelo hardware. A CPU possui pelo menos dois níveis de privilégio (rings ou protection rings):
- Ring 0 (Kernel Mode / modo supervisor) — acesso irrestrito a hardware, a todas as instruções da CPU e a toda a memória física; código do kernel roda aqui.
- Ring 3 (User Mode) — acesso restrito; instruções privilegiadas (acessar diretamente disco, configurar a MMU, mascarar interrupções) são proibidas. Todo código de aplicação roda aqui.
Se um programa em Ring 3 tenta executar uma instrução privilegiada ou acessar memória que
não é sua, a CPU dispara uma exceção (fault) e o kernel assume o controle —
tipicamente enviando o sinal SIGSEGV (o clássico "Segmentation fault"). É esse
mecanismo que garante o isolamento: um bug ou um programa malicioso não
consegue derrubar o sistema inteiro nem espionar a memória de outro processo.
Por que precisamos de syscalls?
Como o código de usuário não pode tocar o hardware diretamente, ele precisa pedir ao kernel que faça a operação em seu nome. Esse pedido é a chamada de sistema (system call) — a única porta de entrada controlada do user space para o kernel space. Abrir um arquivo, criar um processo, enviar um pacote de rede, alocar memória: tudo passa por uma syscall.
Na prática, o programador raramente invoca a syscall "crua". A glibc
(biblioteca C padrão do GNU) oferece funções wrapper com o mesmo nome
(open(), read(), fork()…) que preparam os argumentos,
disparam a instrução syscall e traduzem erros para a variável global
errno. A LPI (LPIC-1 101.1) trata justamente dessa fronteira entre aplicação,
biblioteca e kernel.
Ciclo de uma Syscall
open("/etc/passwd", O_RDONLY) da glibcrax (2 = open no x86-64) e os argumentos em rdi, rsi, rdx…syscall; a CPU muda para Ring 0 e salta para o entry point do kernelraxerrno e devolve o descritor de arquivo ao programaA syscall vista do código C
O exemplo abaixo abre um arquivo e lê seus primeiros bytes usando apenas syscalls
(via wrappers da glibc) — sem fopen/printf de alto nível. Note o
padrão universal do Unix: retorno < 0 indica erro, e o motivo fica em
errno.
#include <fcntl.h> // open, O_RDONLY #include <unistd.h> // read, write, close #include <stdio.h> // perror int main(void) { int fd = open("/etc/hostname", O_RDONLY); // syscall open() if (fd < 0) { perror("open"); return 1; } // erro -> errno char buf[128]; ssize_t n = read(fd, buf, sizeof buf); // syscall read() if (n < 0) { perror("read"); return 1; } write(1, buf, n); // syscall write() no fd 1 = stdout close(fd); // syscall close() return 0; }
$ gcc -Wall le_arquivo.c -o le_arquivo $ ./le_arquivo ubuntu-lab # strace mostra EXATAMENTE as syscalls que o programa fez $ strace -e trace=open,openat,read,write,close ./le_arquivo openat(AT_FDCWD, "/etc/hostname", O_RDONLY) = 3 read(3, "ubuntu-lab\n", 128) = 11 write(1, "ubuntu-lab\n", 11) = 11 close(3) = 0
0 = stdin, 1 = stdout, 2 = stderr.
Por isso write(1, …) escreve na tela. Novos open() recebem o
menor FD livre (por isso o arquivo acima virou o descritor 3).
Categorias de syscalls (Linux tem ~350)
$ man 2 read # documentação da syscall read() $ man 2 syscalls # lista todas as syscalls do Linux $ man 2 open # flags: O_RDONLY, O_CREAT, O_APPEND…
$ strace -e trace=openat ls /etc 2>&1 | head -20 openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libselinux.so.1", O_RDONLY|O_CLOEXEC) = 3 openat(AT_FDCWD, "/etc", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = 3
$ uname -r 6.8.0-51-generic $ uname -a Linux hostname 6.8.0-51-generic #52-Ubuntu SMP Wed Jan 15 2025 x86_64 GNU/Linux $ cat /proc/version Linux version 6.8.0-51-generic (buildd@...) (gcc version 13.3.0)
O que é o Shell?
O shell é um interpretador de comandos — um programa em user space que lê linhas de texto, interpreta-as e instrui o kernel (via syscalls) a executar as ações desejadas. O Bash (Bourne Again SHell) é o shell padrão na grande maioria das distribuições Linux.
Shells mais comuns
Anatomia de um comando
# comando [opções] [argumentos] ls -lah /var/log # ls → nome do programa (executável em /bin/ls) # -lah → flags: long format, all files, human-readable sizes # /var/log → argumento: diretório alvo
Quando você tecla Enter, o Bash faz muito mais do que "rodar o programa". Ele
percorre um pipeline de etapas: expansões (curinga, variáveis, aritmética),
tokenização, resolve se a palavra é um builtin, alias,
função ou executável no PATH, e então usa as syscalls
fork() + execve() para criar o processo. Entender essas etapas é o
que separa "decorar comandos" de realmente dominar a linha de comando (LPI, Linux
Essentials Topic 3; LPIC-1 103.1).
Builtin, alias ou executável?
Nem todo comando é um arquivo no disco. Alguns são builtins — implementados
dentro do próprio Bash (como cd, que precisa ser builtin para mudar o
diretório do próprio shell). Use type para descobrir a natureza de qualquer
comando:
$ type cd echo ls ll cd is a shell builtin echo is a shell builtin ls is aliased to `ls --color=auto' ll is aliased to `ls -alF' $ type -a echo # mostra TODAS as formas de echo (builtin + /usr/bin/echo) echo is a shell builtin echo is /usr/bin/echo
Variáveis: do shell e de ambiente
Uma variável de shell existe só na sessão atual. Ao usar
export, ela vira uma variável de ambiente, herdada por todos
os processos-filho. Não use espaços ao redor do =.
$ nome="Marco" # variável de shell (local) $ echo "Olá, $nome" Olá, Marco $ export EDITOR=vim # vira variável de ambiente $ env | grep EDITOR # aparece no ambiente EDITOR=vim # Variáveis de ambiente importantes $ echo $HOME $USER $SHELL $PATH /home/marco marco /usr/bin/bash /usr/local/bin:/usr/bin:/bin
ls, o shell procura um executável chamado
ls percorrendo os diretórios de $PATH na ordem, e usa o primeiro
que encontrar. Por isso which comando mostra qual arquivo será
executado.
Expansões do shell
Antes de executar, o Bash reescreve a linha de comando. As expansões mais usadas:
# Curinga (globbing): * ? [ ] $ ls *.txt # todos que terminam em .txt $ ls arquivo?.log # ? = exatamente 1 caractere $ ls foto[1-3].png # foto1, foto2 ou foto3 # Expansão de chaves (brace) — gera sequências $ echo arq_{a,b,c}.txt arq_a.txt arq_b.txt arq_c.txt $ mkdir -p projeto/{src,bin,docs} # cria 3 subpastas de uma vez # Til (~) = home; e substituição de comando $( ) $ echo ~ /home/marco $ echo "Hoje é $(date +%A)" Hoje é Monday # Expansão aritmética $(( )) $ echo $((2 + 3 * 4)) 14
Quoting: aspas simples × duplas × escape
Controlar quando o shell expande é essencial. Aspas duplas
preservam espaços mas ainda expandem $variáveis; aspas simples
preservam tudo literalmente.
$ preco=50 $ echo "Custa $preco reais" Custa 50 reais $ echo 'Custa $preco reais' Custa $preco reais $ echo "Aspas: \" e cifrão: \$" Aspas: " e cifrão: $
Comandos essenciais — prática imediata
$ whoami # nome do usuário atual marcos $ id # UID, GID e grupos uid=1000(marcos) gid=1000(marcos) groups=1000(marcos),27(sudo) $ pwd # diretório atual /home/marcos $ hostname # nome da máquina ubuntu-lab
$ cd / # vai para a raiz $ ls # lista o conteúdo bin boot dev etc home lib media mnt opt proc root run srv sys tmp usr var $ cd ~ # vai para o home do usuário $ ls -lah # lista com detalhes
$ man ls # manual completo $ ls --help # ajuda rápida $ type ls # é builtin, alias ou executável? ls is /usr/bin/ls $ which bash # localiza o executável /usr/bin/bash
Redirecionamentos e pipes — o coração do Unix
A filosofia Unix diz: "faça programas pequenos que façam uma coisa bem, e que trabalhem
juntos". Isso só é possível porque cada processo tem três canais padrão — os descritores
0 (stdin), 1 (stdout) e 2 (stderr) vistos no Bloco 2 —
e o shell permite redirecioná-los para arquivos ou conectá-los
entre processos com pipes.
# > redireciona stdout para arquivo (SOBRESCREVE) $ ls /etc > lista.txt # >> ANEXA ao final do arquivo (não apaga) $ date >> lista.txt # < lê stdin de um arquivo $ wc -l < lista.txt 142 # 2> redireciona apenas stderr (erros) $ ls /naoexiste 2> erros.txt # 2>/dev/null → descarta mensagens de erro $ find / -name "*.conf" 2>/dev/null | head # &> redireciona stdout E stderr juntos para o mesmo lugar $ comando &> saida_completa.log
# Encadeie filtros para construir consultas poderosas $ cat /etc/passwd | grep "/bin/bash" | wc -l 3 # quantos usuários têm o bash como shell de login # Os 5 comandos mais usados no seu histórico $ history | awk '{print $2}' | sort | uniq -c | sort -rn | head -5 87 git 64 ls 41 cd 30 vim 22 cat
> conecta um processo a um
arquivo; o pipe | conecta dois processos diretamente na
memória, sem passar por disco — muito mais rápido e a base da composição de comandos.
O que é (e o que não é) uma distribuição
Como visto no Bloco 1, o kernel Linux sozinho não faz nada de útil para o usuário final. Uma distribuição (distro) é a montagem de um sistema completo e instalável: kernel + utilitários GNU + bibliotecas + sistema de init + gerenciador de pacotes + instalador + política de atualizações. A LPI (Linux Essentials Topic 1) destaca que a principal diferença prática entre distros para o administrador está em três eixos:
- Gerenciador de pacotes e formato (
.debviaapt/dpkg×.rpmviadnf/rpm). - Modelo de lançamento: fixed release (versões estáveis periódicas, ex.: Debian, Ubuntu LTS) × rolling release (atualização contínua, ex.: Arch).
- Filosofia e público: estabilidade corporativa (RHEL), facilidade (Ubuntu), minimalismo/containers (Alpine), controle total (Arch).
Principais famílias de distribuições
apt · pacotes .deb · foco em estabilidade e uso em desktop/servidordnf/yum · pacotes .rpm · padrão em ambiente corporativozypper · pacotes .rpm · ferramenta YaST para administraçãopacman · rolling release · alta personalização, curva íngremeapk · ~5 MB base · padrão em containers DockerGerenciadores de pacotes — comandos equivalentes
Saber "traduzir" a mesma operação entre famílias é uma habilidade cobrada na LPIC-1 (Objectives 102.4 e 102.5). Todos resolvem o mesmo problema — instalar software e suas dependências — com sintaxes diferentes:
| Operação | Debian / Ubuntu (apt) |
Red Hat / Fedora (dnf) |
Arch (pacman) |
|---|---|---|---|
| Atualizar índice | apt update | dnf check-update | pacman -Sy |
| Instalar pacote | apt install nginx | dnf install nginx | pacman -S nginx |
| Remover pacote | apt remove nginx | dnf remove nginx | pacman -R nginx |
| Atualizar tudo | apt upgrade | dnf upgrade | pacman -Su |
| Buscar pacote | apt search termo | dnf search termo | pacman -Ss termo |
| Que pacote tem o arquivo? | dpkg -S /caminho | rpm -qf /caminho | pacman -Qo /caminho |
# O arquivo padronizado /etc/os-release funciona em QUALQUER distro moderna $ cat /etc/os-release PRETTY_NAME="Ubuntu 22.04.4 LTS" NAME="Ubuntu" VERSION_ID="22.04" ID=ubuntu ID_LIKE=debian $ lsb_release -a 2>/dev/null # alternativa (nem sempre instalada)
Hierarquia do Sistema de Arquivos (FHS)
O Filesystem Hierarchy Standard é uma especificação que define onde cada tipo de arquivo deve ficar, garantindo que um administrador saiba encontrar as coisas em qualquer distribuição. Duas ideias organizam a hierarquia (LPIC-1 104.7):
- Estático × variável:
/usre/binquase não mudam (podem ser read-only);/vare/tmpmudam o tempo todo. - Compartilhável × local:
/usrpode ser compartilhado por rede entre máquinas;/etce/bootsão específicos de cada host.
/bin, /sbin e
/lib são apenas links simbólicos para /usr/bin,
/usr/sbin e /usr/lib. Confirme com ls -ld /bin — você
verá algo como /bin -> usr/bin. A separação histórica existia porque
/usr podia estar em outro disco montado depois do boot.
Caminho absoluto × relativo
Um caminho absoluto começa em / (a raiz) e é sempre o mesmo,
independente de onde você esteja. Um caminho relativo parte do diretório
atual. . é o diretório atual, .. é o pai e ~ é o home.
$ cd /var/log $ cat syslog # relativo → /var/log/syslog $ cat /etc/hostname # absoluto → sempre o mesmo $ cd ../.. # sobe dois níveis → / $ cd - # volta ao diretório anterior
$ ls -ld /bin /sbin /lib # veja os symlinks do /usr merge $ ls -lah / $ du -sh /var/log/* 2>/dev/null | sort -rh | head -10 $ file /dev/null /dev/zero /dev/random /dev/null: character special (1/3) /dev/zero: character special (1/5) /dev/random: character special (1/8)
O que é, afinal, um processo?
No Bloco 1 vimos o processo como uma das grandes abstrações do SO. Agora vamos
abrir a caixa. Um processo é um programa em execução: não é
o arquivo no disco (isso é o programa), mas a instância viva dele —
código carregado na memória, mais todo o estado que o kernel mantém para acompanhá-lo. O
mesmo programa (/usr/bin/vim) pode originar dezenas de processos simultâneos e
independentes.
A imagem de um processo na memória
Cada processo enxerga seu próprio espaço de endereços virtual (Bloco 2), organizado em regiões bem definidas:
Além da memória, o kernel guarda para cada processo um bloco de controle
(o PCB, no Linux a estrutura task_struct) com sua identidade e
contexto:
Como um processo nasce: fork() + execve()
No Unix, um processo não é criado do nada — ele é sempre clonado de um pai.
O par de syscalls fork() + execve() é o coração do modelo:
fork() — o processo pai se duplica; o kernel cria um filho com uma cópia do espaço de endereços (via copy-on-write, sem copiar de fato até haver escrita). O filho recebe um novo PID.fork() retorna duas vezes: 0 no filho e o PID do filho no pai — é assim que cada um sabe quem é.execve("/bin/ls", …), que substitui sua imagem de memória pelo novo programa, mantendo o mesmo PID e os descritores herdados.wait()/waitpid() para aguardar o término do filho e coletar seu código de saída (reaping).ls, o Bash faz
fork() de si mesmo e o filho faz execve() do ls. Por
isso o filho herda o stdout (fd 1) do terminal — e por isso o resultado aparece
na sua tela. O PID 1 (systemd/init) é o ancestral de
todos: veja com pstree.
Estados de um processo
O kernel move cada processo entre estados conforme ele disputa a CPU ou espera por I/O. A
coluna STAT de ps aux mostra a letra do estado:
| Código | Estado | Significado |
|---|---|---|
R | Running / Runnable | Executando na CPU ou na fila pronto para executar |
S | Sleeping (interruptível) | Aguardando um evento (teclado, rede, timer); pode ser acordado por sinal |
D | Uninterruptible sleep | Bloqueado em I/O de disco; não pode ser interrompido (nem por kill -9) |
T | Stopped | Suspenso por Ctrl+Z ou sinal SIGSTOP |
Z | Zombie | Já terminou, mas o pai ainda não coletou seu código de saída |
Um zumbi (Z) é normal e efêmero — some assim que o pai faz wait().
Vira problema só quando o pai esquece de coletar e acumula zumbis. Um órfão
(pai morreu antes do filho) é adotado pelo PID 1, que faz o wait() por ele.
Como o kernel decide quem roda: o escalonador
Há sempre mais processos prontos (R) do que núcleos de CPU. O
escalonador (scheduler, no Linux o CFS — Completely Fair
Scheduler) reparte a CPU em fatias de tempo de milissegundos e alterna
os processos tão rápido que criam a ilusão de simultaneidade (multitarefa preemptiva,
Bloco 1). Trocar de processo exige um context switch: salvar os registradores
do atual e carregar os do próximo — barato, mas não gratuito.
A prioridade influencia quanto tempo cada um recebe. O valor
nice vai de -20 (mais prioritário) a +19 (mais
"gentil", cede a CPU). Usuários comuns só conseguem aumentar o nice (baixar a
prioridade); baixá-lo exige root.
$ ps -o pid,ppid,stat,ni,comm -p $$ # dados do próprio shell ($$ = PID atual) PID PPID STAT NI COMMAND 2841 2833 Ss 0 bash # Iniciar um processo com prioridade reduzida $ nice -n 10 sleep 100 & $ renice -n 15 -p 4567 # mudar a prioridade de um processo já rodando # O kernel expõe TUDO sobre um processo em /proc/PID $ cat /proc/$$/status | grep -E "State|Pid|PPid|Uid" State: S (sleeping) Pid: 2841 PPid: 2833 Uid: 1000 1000 1000 1000 $ ls /proc/$$/fd # descritores de arquivo abertos pelo shell 0 1 2 255
Sinais: conversando com processos
O kernel entrega sinais — interrupções assíncronas — para pedir que um
processo pare, recarregue ou termine. Você os dispara com Ctrl+C, Ctrl+Z
ou o comando kill (que, apesar do nome, apenas envia um sinal):
Por que aprender a ler o man vale mais que decorar comandos
Ninguém memoriza todas as flags de todos os comandos — nem precisa. Um administrador
proficiente sabe encontrar a resposta na documentação que já vem instalada
na própria máquina, offline. A porta de entrada é o man (manual): cada
comando, syscall, arquivo de configuração e função de biblioteca tem sua página. Saber
navegá-las é objetivo explícito da LPI (LPIC-1 103.1).
As seções do manual
O manual é dividido em seções numeradas. Isso importa porque o mesmo nome
pode existir em várias — por exemplo, existe o comando printf (seção 1)
e a função C printf (seção 3):
| Seção | Conteúdo | Exemplo |
|---|---|---|
1 | Comandos de usuário | man 1 ls |
2 | Chamadas de sistema (syscalls) | man 2 read |
3 | Funções de biblioteca (glibc) | man 3 printf |
4 | Arquivos de dispositivo (/dev) | man 4 null |
5 | Formatos de arquivo e config | man 5 passwd |
6 | Jogos e diversões | man 6 fortune |
7 | Miscelânea (convenções, protocolos) | man 7 signal |
8 | Comandos de administração (root) | man 8 mount |
man passwd abre a seção 1 (o comando que
troca a senha); man 5 passwd abre a seção 5 (o formato do arquivo
/etc/passwd). Quando há ambiguidade, o número da seção é obrigatório.
Anatomia de uma página de manual
Toda página segue a mesma estrutura padronizada — aprenda a "saltar" direto para a parte que interessa:
[ ] = opcional, ... = repetívelNavegando dentro do man
O man usa o paginador less. As teclas essenciais para não ficar
perdido:
| Tecla | Ação |
|---|---|
| Espaço / b | Avançar / voltar uma tela |
| ↑ ↓ | Rolar linha a linha |
| /padrão Enter | Buscar "padrão" para frente |
| n / N | Próxima / anterior ocorrência da busca |
| g / G | Ir ao início / fim da página |
| q | Sair |
Quando você não sabe o nome do comando
O maior valor do sistema de manuais aparece quando você sabe o que quer fazer, mas não qual comando usar. É aí que entram a busca por palavra-chave e o resumo:
# Buscar por palavra-chave em TODAS as descrições (NAME) das páginas $ apropos "copy files" # idêntico a: man -k "copy files" cp (1) - copy files and directories install (1) - copy files and set attributes scp (1) - secure copy (remote file copy program) # Resumo de uma linha de um comando (a seção NAME) $ whatis ls # idêntico a: man -f ls ls (1) - list directory contents # Em quais seções existe uma página com esse nome? $ man -f printf printf (1) - format and print data printf (3) - formatted output conversion
Além do man: outras fontes na máquina
$ ls --help # ajuda rápida embutida no próprio programa (builtins e GNU) $ help cd # ajuda de um BUILTIN do Bash (cd não tem man próprio) $ info coreutils # manual hipertexto do GNU, mais extenso que o man $ ls /usr/share/doc/ # READMEs, changelogs e exemplos dos pacotes instalados
--help para lembrar rápido uma flag,
man para entender um comando a fundo, apropos quando não sabe o
nome, e sempre siga o SEE ALSO — é como um comando "puxa" o próximo.
man, info, /usr/share/doc).
Laboratórios Guiados
Exploração do Sistema de Arquivos e do /proc
Navegação FHS, leitura de arquivos do kernel e coleta de informações do sistema
Objetivos do Lab 1
- Navegar pela hierarquia FHS com
cdels - Ler informações do kernel via
/proc - Entender o que são arquivos de dispositivo em
/dev - Usar
findpara localizar arquivos
Parte A — Explorando a raiz e /proc
# 1. Ver informações do processador $ cat /proc/cpuinfo | grep "model name" | head -1 model name : Intel(R) Core(TM) i7-10750H CPU @ 2.60GHz # 2. Ver informações de memória RAM $ cat /proc/meminfo | head -5 MemTotal: 16384000 kB MemFree: 8192000 kB MemAvailable: 10240000 kB Buffers: 512000 kB Cached: 2048000 kB # 3. Ver tempo ligado (uptime do kernel) $ cat /proc/uptime 3600.12 7120.45 # 1o campo: segundos ligado | 2o: soma do tempo idle de todos os CPUs # 4. Ver sistemas de arquivos suportados pelo kernel $ cat /proc/filesystems nodev sysfs nodev tmpfs nodev bdev ext3 ext4 xfs nodev proc # 5. Informações do PID 1 (init/systemd) $ cat /proc/1/cmdline | tr '\0' ' ' /sbin/init splash $ ls -la /proc/1/ # Explore: fd/, maps, status, environ…
Parte B — Dispositivos e Filesystem
# 6. Ver dispositivos de bloco montados $ lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS sda 8:0 0 20G 0 disk ├─sda1 8:1 0 512M 0 part /boot/efi ├─sda2 8:2 0 1G 0 part /boot └─sda3 8:3 0 18.5G 0 part / # 7. Ver sistemas de arquivos montados $ df -hT Filesystem Type Size Used Avail Use% Mounted on /dev/sda3 ext4 19G 5.2G 13G 29% / tmpfs tmpfs 7.9G 0 7.9G 0% /dev/shm # 8. Procurar arquivos de configuração modificados recentemente $ find /etc -name "*.conf" -mtime -7 -ls 2>/dev/null | head -10 # 9. Contar linhas em /var/log/syslog $ wc -l /var/log/syslog 2>/dev/null || wc -l /var/log/kern.log 8472 /var/log/syslog # 10. Ver últimas 5 linhas do log do sistema $ tail -5 /var/log/syslog Jun 7 10:00:01 ubuntu CRON[1234]: (root) CMD (command -v debian-sa1 > /dev/null && debian-sa1 1 1)
Parte C — Redirecionamentos e pipes
# 11. Redirecionar saída para arquivo $ uname -a > /tmp/sysinfo.txt $ cat /proc/cpuinfo >> /tmp/sysinfo.txt $ wc -l /tmp/sysinfo.txt # 12. Filtrar com grep e contar $ grep -c "processor" /proc/cpuinfo 8 # número de CPUs lógicas # 13. Pipeline: listar arquivos maiores em /usr/bin $ ls -lhS /usr/bin | head -10
/? Quando o sistema foi iniciado?
Processos, Permissões e Scripts Básicos
Gerenciamento de processos, modelo de permissões Unix e criação do primeiro script
Parte A — Processos
# 1. Listar todos os processos $ ps aux | head -15 USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.1 169460 13520 ? Ss 09:00 0:02 /sbin/init splash root 2 0.0 0.0 0 0 ? S 09:00 0:00 [kthreadd] # 2. Árvore de processos $ pstree -p | head -20 # 3. Ver processos em tempo real $ top # pressione 'q' para sair $ htop # versão melhorada (instalar se necessário) # 4. Executar processo em background $ sleep 300 & [1] 4567 $ jobs [1]+ Running sleep 300 & $ ps -p 4567 PID TTY TIME CMD 4567 pts/0 00:00:00 sleep # 5. Matar o processo $ kill 4567 [1]+ Terminated sleep 300 # 6. Ver sinais disponíveis $ kill -l | head -5 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
Parte B — Modelo de Permissões Unix
# 7. Criar arquivo e ver permissões $ touch /tmp/teste.txt $ ls -l /tmp/teste.txt -rw-r--r-- 1 marcos marcos 0 Jun 7 10:15 /tmp/teste.txt # _ rw- r-- r-- # │ │ │ └── outros: leitura # │ │ └────── grupo: leitura # │ └────────── dono: leitura + escrita # └───────────── tipo: '-' arquivo, 'd' dir, 'l' symlink # 8. Chmod em notação octal e simbólica $ chmod 755 /tmp/teste.txt $ ls -l /tmp/teste.txt -rwxr-xr-x 1 marcos marcos 0 Jun 7 10:15 /tmp/teste.txt $ chmod u-x,o-r /tmp/teste.txt -rw-r-x--- ... # 9. Criar diretório e ver herança $ mkdir -p /tmp/lab2/subdir $ ls -la /tmp/lab2/ # 10. Verificar identidade de um arquivo $ stat /tmp/teste.txt File: /tmp/teste.txt Size: 0 Blocks: 0 IO Block: 4096 regular empty file Device: 8,3 Inode: 131073 Links: 1 Access: (0640/-rw-r-----) Uid: (1000/marcos) Gid: (1000/marcos)
Parte C — Primeiro Script Bash
# 11. Criar o script $ cat > ~/sysreport.sh <<'EOF' #!/usr/bin/env bash echo "=== Relatório do Sistema ===" echo "Data/Hora : $(date)" echo "Hostname : $(hostname)" echo "Usuário : $(whoami)" echo "Kernel : $(uname -r)" echo "Uptime : $(uptime -p)" echo "" echo "--- CPU ---" grep "model name" /proc/cpuinfo | head -1 | cut -d: -f2 echo "" echo "--- Memória ---" free -h echo "" echo "--- Disco ---" df -h / EOF # 12. Tornar executável e rodar $ chmod +x ~/sysreport.sh $ ~/sysreport.sh
=== Relatório do Sistema ===
Data/Hora : Sat Jun 7 10:20:00 UTC 2026
Hostname : ubuntu-lab
Usuário : marcos
Kernel : 6.8.0-51-generic
Uptime : up 1 hour, 20 minutes
--- CPU ---
Intel(R) Core(TM) i7-10750H CPU @ 2.60GHz
--- Memória ---
total used free
Mem: 16Gi 5.2Gi 8.1Gi
Swap: 2.0Gi 0B 2.0Gi
--- Disco ---
Filesystem Size Used Avail Use% Mounted on
/dev/sda3 19G 5.2G 13G 29% /
Desafio Prático Individual
Duração: 25 minutos |
Formato: Individual |
Entregável: Arquivo /tmp/relatorio_individual.txt
Missão
Você recebeu acesso a um servidor Linux desconhecido. Produza um relatório de reconhecimento do sistema respondendo às perguntas abaixo usando apenas a linha de comando. Todos os comandos devem ser registrados no arquivo de relatório.
Perguntas a responder
# Crie o arquivo de relatório $ exec > >(tee /tmp/relatorio_individual.txt) 2>&1 $ echo "Aluno: [Seu Nome] — $(date)" # Q1: Qual versão exata do kernel está em uso? $ uname -r # Q2: Quantos usuários existem no sistema (linhas em /etc/passwd)? $ wc -l /etc/passwd # Q3: Qual é o shell padrão do usuário atual? $ echo $SHELL # Q4: Quais shells estão disponíveis no sistema? $ cat /etc/shells # Q5: Qual é o maior arquivo em /usr/bin? (nome e tamanho) $ ls -lhS /usr/bin | head -3 # Q6: Quantos processos estão rodando agora? $ ps aux | wc -l # Q7: Qual processo consome mais CPU no momento? $ ps aux --sort=-%cpu | head -3 # Q8: Qual é o inode do arquivo /etc/passwd? $ stat /etc/passwd | grep Inode # Q9: Crie um arquivo em /tmp com seu nome e exiba suas permissões em octal $ touch /tmp/prova.txt $ stat -c "%a %n" /tmp/prova.txt # Q10: Escreva uma linha de comando ONE-LINER que mostre # apenas o nome dos 5 processos que mais consomem memória $ ps aux --sort=-%mem | awk 'NR>1{print $11}' | head -5
Bônus (para alunos avançados)
# Crie um script que monitora o uso de CPU a cada 2 segundos por 10 vezes $ for i in $(seq 1 10); do echo -n "$(date +%T) CPU: " top -bn1 | grep "Cpu(s)" | awk '{print $2}' | tr -d '%us,' sleep 2 done
Referência Rápida de Comandos
Navegação
pwd → diretório atual cd → mudar diretório ls -la → listar com detalhes tree → árvore visual find → buscar arquivos
Arquivos
cat / less / more → ler head / tail → início/fim cp / mv / rm → copiar/mover/apagar touch → criar/atualizar timestamp stat / file → metadados
Sistema
uname -a → info do kernel uptime → tempo ligado free -h → memória df -h → disco lsblk → dispositivos
Processos
ps aux → listar processos top/htop → monitor interativo kill PID → encerrar processo jobs/bg/fg → controle de jobs pstree → árvore de processos
Permissões
chmod 755 → alterar permissões chown → mudar dono chgrp → mudar grupo umask → máscara padrão id / whoami → identidade
Texto / Filtros
grep → buscar padrões wc -l → contar linhas sort → ordenar cut → extrair campos awk → processamento avançado
Checklist de Avaliação Prática
Pontuação Sugerida
Executa comandos básicos com orientação; precisa de ajuda para navegar; entende conceitualmente o que é um SO mas não sabe explorar autonomamente.
Navega e usa filtros sem ajuda; escreve scripts simples; explica syscalls e FHS; resolve o desafio com referência à documentação.
Resolve o desafio completo com bônus; usa strace e /proc
proficientemente; explica trade-offs entre distribuições; scripts robustos.
Tarefa de Fixação (para casa)
Entrega: próxima aula
A tarefa deve ser entregue como um arquivo tarefa01.sh — um script Bash
executável que, quando rodado, exibe todos os resultados abaixo.
Requisitos do script
- Exibir nome, versão do kernel e distribuição (leia
/etc/os-release) - Listar os 5 maiores arquivos em
/var/logcom tamanhos legíveis - Mostrar quantos processos cada usuário tem rodando (dica:
ps aux | awk) - Exibir as 3 partições com maior uso percentual de disco
- Criar um diretório
~/lab01com 3 subdiretórios e permissões diferentes - Escrever um here-document com um mini-relatório em
~/lab01/relatorio.txt - Usar pelo menos 1 loop, 1 condicional e 1 pipe no script
- Bônus: Detectar se
systemdé o init e listar os 5 serviços ativos
#!/usr/bin/env bash set -euo pipefail echo "=== Tarefa 01 — Fundamentos de SO e Linux ===" echo "Aluno: SEU NOME AQUI" echo "Data: $(date '+%Y-%m-%d %H:%M:%S')" echo "" # 1. Informações do sistema echo "--- Sistema ---" source /etc/os-release echo "Distro : $PRETTY_NAME" echo "Kernel : $(uname -r)" echo "Arch : $(uname -m)" echo "" # 2. Maiores arquivos em /var/log echo "--- Maiores arquivos em /var/log ---" # ... seu código aqui ... echo "" # 3. Processos por usuário echo "--- Processos por usuário ---" # ... seu código aqui ... echo "" # 4–8: complete os demais requisitos...
Recursos e Referências
LPI (referência principal)
Documentação online
- 📖
man bash— manual completo do Bash - 📖 The Linux Kernel Documentation
- 📖 Filesystem Hierarchy Standard (FHS 3.0)
Leitura complementar
Orientações Gerais
Como aproveitar melhor este módulo
- Rode o
straceem um simpleslspara ver, ao vivo, quantas chamadas de sistema um comando trivial dispara — é o que torna o conceito de syscall concreto - Não apenas execute os comandos: procure explicar em voz alta a saída de cada um antes de seguir para o próximo
- Sempre que possível, relacione cada comando ao objetivo LPI correspondente — isso constrói consciência do caminho de certificação
- Refaça os dois laboratórios sem olhar o passo a passo; a autonomia é o objetivo final
- Tente o bônus do desafio: é onde os conceitos de processo, filtro e script se juntam
- Mantenha o
manaberto ao lado — consultar a documentação é uma habilidade tão importante quanto memorizar comandos
Erros comuns a evitar
- Confundir
/(raiz) com~(home) ao copiar caminhos - Esquecer o espaço entre o comando e as opções (
ls-lavsls -la) - Usar
rmsem cuidado — lembre-se de que não há lixeira no terminal - Interpretar mal a saída de
ps aux: ela mostra os processos de todos os usuários, não apenas os seus