UFPR – Setor Palotina | Curso de Computação

Prática de Sistemas Operacionais

Professor Jéfer Benedett Dorr | Disciplina DEE355 – 2025/2026

📋 Sumário da Prática

Objetivos da prática

Como usar esta prática

Esta prática tem caráter investigativo: o objetivo não é apenas executar, mas compreender como o sistema operacional funciona internamente.

1. Identificação de Hardware e Sistema

O kernel mantém várias informações sobre CPU, arquitetura e sistema operacional em arquivos virtuais do /proc e em utilitários dedicados.

O diretório /proc é um sistema de arquivos virtual criado pelo kernel. Ele não existe fisicamente em disco e seus arquivos são gerados dinamicamente para representar o estado interno do sistema.

📌 Conceito importante: O diretório /proc é um sistema de arquivos virtual criado pelo kernel. Ele não existe fisicamente em disco — seus arquivos são gerados dinamicamente para representar o estado interno do sistema, como processos em execução, configurações de hardware e uso de memória. Cada arquivo dentro de /proc é uma "janela" para informações do kernel em tempo real.

# Informações da CPU (incluindo flags de virtualização)
grep -m 1 "flags" /proc/cpuinfo

# Informações completas da CPU
lscpu
          
# flags específicas de virtualização
lscpu | grep Flags

# Versão do kernel e arquitetura (com data de compilação)
uname -a

# Informações completas do sistema (hardware, kernel, SO)
hostnamectl

# Detalhes específicos da distribuição
cat /etc/os-release

📌 Inspeção completa de hardware com lshw

O comando lshw fornece uma visão detalhada de todos os componentes de hardware do sistema, incluindo CPU, memória, discos, rede e dispositivos conectados.

📌 Conceito importante: Diferente de comandos como lscpu ou lsblk, que mostram partes específicas do sistema, o lshw apresenta uma visão completa e hierárquica do hardware detectado pelo kernel.

# Instalar (se necessário)
sudo apt install lshw

# Visão completa (pode ser longa)
sudo lshw

# Resumo mais simples
sudo lshw -short

# Filtrar apenas memória
sudo lshw -class memory

# Filtrar apenas rede
sudo lshw -class network

O lshw também pode mostrar informações como velocidade da RAM, modelo exato da placa-mãe e interfaces de rede — dados que nem sempre aparecem em outros comandos.

# Navegando no /proc - informações de um processo específico # Substitua [PID] pelo número do processo (ex: 1 para systemd) cat /proc/[PID]/status | head -15

📌 Histórico de comandos

history
!10   # executa comando 10
Relatório – Questão 1.1
Localize a flag vmx (Intel) ou svm (AMD) nos comandos grep -m 1 "flags" /proc/cpuinfo ou lscpu | grep Flags.
O que a presença (ou ausência) dessa flag indica sobre a capacidade de virtualização do processador?

Questão 1.2
Qual é a versão exata do kernel Linux que está rodando na máquina? (mostre a linha completa do uname -a)

Questão 1.3
O diretório /proc ocupa espaço em disco? Explique.

Questão 1.4
Execute sudo lshw -short. Quais são os principais dispositivos listados?

Questão 1.5
Qual a diferença entre o lshw e o lscpu ou lsblk?

2. Memória Física, Cache e Swap

Após identificar o hardware no módulo anterior, agora vamos entender como o sistema operacional utiliza um dos recursos mais críticos: a memória. Veremos como o Linux gerencia RAM, cache e swap para manter o sistema eficiente.

Entenda como o sistema gerencia RAM, cache e área de troca (swap).

Nem toda memória "usada" significa indisponível. O Linux utiliza memória livre para cache de disco, que pode ser liberado automaticamente quando necessário.

📌 Conceito importante: No Linux, nem toda memória "usada" significa indisponível. O sistema utiliza memória livre para cache de disco — ele guarda dados recentemente acessados para acelerar operações futuras. Esse cache pode ser liberado instantaneamente quando um programa precisa de mais RAM. Já o swap é uma área em disco que funciona como extensão da memória física: quando a RAM fica cheia, páginas de memória menos utilizadas são movidas para o swap, evitando que o sistema fique sem recursos, mas com impacto no desempenho.

# Visão geral amigável de memória (total, usada, swap)
free -h

# Estatísticas de memória virtual em tempo real (5 amostras)
# si = swap in, so = swap out - se altos, sistema está sofrendo
vmstat 1 5

# Dados brutos da memória (demonstra que "tudo é arquivo")
cat /proc/meminfo | head -20

          # Monitoramento interativo (tecla 1 = núcleos, M = ordenar por memória)
top

top -p [PID]          
        

Dica de Teclas no TOP / HTOP

Use estes atalhos enquanto o monitor estiver aberto:

🧪 Experimento: O que acontece quando falta memória?


stress --vm 2 --vm-bytes 1G --timeout 20s

Observe vmstat e free ao mesmo tempo.

Relatório – Questão 2.1
Qual o total de memória RAM física instalada? E quanto está realmente disponível para novos processos agora (Mem: available)?

Questão 2.2
Abra várias abas pesadas no navegador e rode vmstat 1 novamente. Os valores si e so aumentaram? O que isso significa na prática para o desempenho do computador?
Questão 2.3
Por que a memória "used" pode ser alta mesmo com poucos programas abertos? Explique o papel do cache.

3. Gerenciamento de Processos e Hierarquia

Depois de compreender como a memória é gerenciada, agora analisamos como os programas são executados. Cada aplicação em execução é um processo, e o sistema operacional precisa gerenciar milhares deles simultaneamente.

Todo programa em execução é um processo. Vamos ver a árvore e o consumo de recursos.

Cada processo pode estar em diferentes estados: Running, Sleeping, Stopped, Zombie, entre outros. Esses estados podem ser observados com ps ou top.

📌 Conceito importante: Cada processo no Linux pode estar em diferentes estados durante sua execução:

Esses estados podem ser observados com ps aux ou top na coluna STAT.

# Lista completa com hierarquia em formato árvore (mostra pais/filhos)
ps auxf

# Visualizador interativo (aperte H para ver threads)
htop

# Tempo de atividade e carga média (1, 5 e 15 minutos)
uptime

# Explorando o /proc - metadados de um processo específico
# Substitua [PID] pelo número do processo (ex: PID do navegador)
cat /proc/[PID]/status | grep -E "Name|Pid|PPid|Threads|VmSize"

📌 Prioridade de processos (nice)

# Executar com baixa prioridade
nice -n 10 sleep 100

# Alterar prioridade de um processo
renice 5 -p [PID]

Controla como o scheduler do sistema distribui CPU.

Relatório – Questão 3.1
No htop, pressione H (letra H maiúscula). O que muda na exibição? Por que isso é útil?

Questão 3.2
Por que um único navegador (Chrome / Firefox / Edge) aparece com dezenas de processos? Explique o conceito de multi-process architecture utilizado por navegadores modernos. Questão 3.3
Existe algum processo no estado "sleeping"? O que isso significa?

4. Logs do Sistema e Mensagens do Kernel

Agora que sabemos como processos funcionam, precisamos entender como diagnosticar problemas. O sistema operacional registra eventos importantes em logs, fundamentais para análise e depuração.

O kernel e os serviços registram eventos importantes em logs - essencial para diagnóstico.

Os logs são fundamentais para administração de sistemas, pois registram erros de hardware, autenticação, serviços e eventos do kernel.

📌 Conceito importante: Os logs são o "diário de bordo" do sistema operacional. Eles registram desde a inicialização do kernel até falhas de hardware, tentativas de login, erros de aplicações e eventos de segurança. Consultar logs é a primeira ação em qualquer diagnóstico de problemas. O dmesg foca nas mensagens do kernel (hardware, drivers, boot), enquanto o journalctl centraliza logs de todos os serviços gerenciados pelo systemd.

# Mensagens do buffer do kernel (detecção de hardware, erros de driver)
dmesg -T | tail -n 30

# Monitorar mensagens do kernel em tempo real
sudo dmesg -wT

# Logs do systemd com contexto (formato legível)
journalctl -xe | head -30

# Logs dos últimos boots
journalctl -b -1 | tail -30
Relatório – Questão 4.1
Qual a diferença entre dmesg e journalctl?

5. Armazenamento e Barramentos

Além de memória e processos, o sistema precisa armazenar dados de forma persistente. Neste módulo, exploramos como o Linux organiza discos, partições e dispositivos.

Como o kernel organiza discos, partições e identifica periféricos conectados.

O comando df mostra uso de espaço, mas arquivos também consomem inodes. Um disco pode encher de arquivos pequenos mesmo com espaço livre.

📌 Conceito importante: Além do espaço em disco medido em bytes, o sistema de arquivos também gerencia inodes. Cada arquivo ou diretório consome um inode, que armazena metadados (permissões, timestamps, localização dos blocos de dados). É possível que o disco tenha espaço livre, mas esteja "cheio" porque todos os inodes disponíveis foram utilizados — isso ocorre com frequência em sistemas que armazenam milhões de arquivos pequenos (ex: servidores web com muitos arquivos de cache). Use df -i para verificar o consumo de inodes.

# Topologia de discos e partições em árvore (visualização inicial)
lsblk

# Espaço usado em disco e pontos de montagem
df -h

# Consumo de inodes          
df -i

# Dispositivos PCI (placas de vídeo, rede, som, etc)
lspci | head -20

# Dispositivos USB conectados (mouse, pendrive, teclado)
lsusb

# Versão mais detalhada do lsblk
lsblk -f

📌 Espaço por diretório com du

# Tamanho de diretórios
du -h --max-depth=1

# Top diretórios mais pesados
du -h --max-depth=1 | sort -hr | head -10

Enquanto o df mostra o uso do disco, o du mostra quem está consumindo espaço.

Relatório – Questão 5.1
Qual o tamanho total e o espaço usado da partição raiz (/) segundo o df -h?

Questão 5.2
Algum dispositivo USB aparece no lsusb? Qual o nome/ID do dispositivo (ex: mouse, pendrive, teclado)? Questão 5.3
O que são inodes? O sistema pode ficar cheio mesmo com espaço livre?

6. Criação de Processos e Scripts Multi-Linguagem

Compreendendo armazenamento e processos, agora vamos executar programas na prática. Aqui veremos como diferentes linguagens interagem com o sistema operacional.

O sistema operacional executa diferentes tipos de programas: interpretados e compilados.

Cada execução cria um novo processo no sistema. Podemos observar isso consultando a lista de processos logo após executar os programas.

# Ver processos criados
ps aux | grep hello

Python (interpretado)

echo "print('Olá, Mundo do Python!')" > hello.py
python3 hello.py

C (compilado com gcc)

cat <<EOF > hello.c
#include 
int main() {
    printf("Olá, Mundo do C!\n");
    return 0;
}
EOF

gcc hello.c -o hello
./hello

Bash (shell script)

echo 'echo "Olá do Bash!"' > hello.sh
chmod +x hello.sh
./hello.sh

Perl (interpretado)

echo 'print "Olá do Perl!\n";' > hello.pl
perl hello.pl

📌 Observando chamadas de sistema com strace

O comando strace permite observar as system calls (chamadas de sistema) que um programa faz ao kernel durante sua execução.

📌 Conceito importante: Programas não acessam diretamente o hardware. Eles solicitam serviços ao kernel através de system calls, como leitura de arquivos, criação de processos e comunicação de rede. O strace permite visualizar essas interações em tempo real.

# Instalar (se necessário)
sudo apt install strace

# Executar um programa simples com rastreamento
strace ls

# Executar seu programa Python com strace
strace python3 hello.py

# Filtrar apenas chamadas de arquivo
strace -e trace=open,read,write ls

# Salvar saída em arquivo (mais organizado)
strace -o log.txt ls

Você verá chamadas como open(), read(), write(), que mostram como o programa interage com o sistema operacional.

📌 Localizando comandos no sistema

# Onde está o executável
which python3

# Tipo do comando (binário, alias, builtin)
type ls

Mostra como o shell resolve comandos — essencial para entender execução.

📌 Variáveis de ambiente

# Listar todas as variáveis
printenv

# Ver valor de uma variável específica
echo $PATH

# Definir variável para a sessão atual
export MINHA_VAR="valor"

# Definir variável permanentemente (via .bashrc)
echo 'export MINHA_VAR="valor"' >> ~/.bashrc && source ~/.bashrc

# Executar comando com variável temporária única
VAR=teste python3 hello.py

Variáveis de ambiente influenciam o comportamento dos programas. O comando export torna a variável disponível para todos os processos filhos da sessão atual, enquanto a edição do arquivo .bashrc garante que ela seja carregada em todos os novos terminais.

📌 Medindo tempo de execução

time python3 hello.py
Relatório – Questão 6.1
Qual a diferença no processo de execução entre os programas em Python/Perl (interpretados) e o em C (compilado)?

Questão 6.2
Podemos executar o script Bash usando bash hello.sh ou ./hello.sh? Qual a diferença? Questão 6.3
Execute o programa várias vezes e observe o comando ps. Cada execução possui um PID diferente? O que isso indica sobre criação de processos?

7. Interação Gráfica Simples via Terminal (Zenity outros similares seriam xdialog, gdialog, kdialog)

Até agora utilizamos apenas o terminal. Neste módulo, veremos como o sistema operacional também fornece interfaces gráficas e como elas podem ser acionadas via linha de comando.

Demonstração de como o shell pode invocar interfaces gráficas nativas.

Caso o comando não funcione, instale o pacote com:

sudo apt install zenity
# Janela de informação simples
zenity --info --text="Olá, esta é uma janela gerada pelo Terminal!" --title="Aula de SO"

# Janela de entrada de texto com captura da resposta
NOME=$(zenity --entry --text="Digite seu nome:")
echo "O aluno digitou: $NOME"
Relatório – Questão 7.1
O que acontece se o pacote zenity não estiver instalado?

Questão 7.2
Como o comando zenity se relaciona com o conceito de system calls e bibliotecas gráficas?

8. Evolução: Rede e Conectividade

O sistema operacional também é responsável pela comunicação em rede. Neste módulo, exploramos como o Linux gerencia interfaces, conexões e protocolos.

O kernel gerencia a pilha de rede (TCP/IP). Vamos ver interfaces, rotas e conexões ativas.

# Interfaces e IPs
ip addr show

# Teste de conectividade e latência
ping -c 4 google.com
          
# Tabela de roteamento
ip route

# Conexões ativas + portas + processos
ss -tunlp

# Latência + rota combinada
mtr -c 5 google.com

# Portas em LISTEN
ss -tuln | grep LISTEN

📌 Requisições HTTP via terminal

# Fazer requisição web
curl https://example.com

# Ver apenas cabeçalhos
curl -I https://google.com

Permite interagir com serviços web diretamente pelo terminal.

Relatório – Questão 8.1
Pelo ss -tunlp, existe serviço LISTEN na porta 22 (SSH) ou 80/443?
Qual processo e PID?

Questão 8.2
No ip addr, qual o IP da interface principal (ex: enp0s3, wlan0)? IPv4 ou IPv6? Questão 8.3
Qual foi a latência média observada no ping? Esse valor é alto ou baixo para sua rede?

9. Monitoramento em Tempo Real

Agora que conhecemos diversos componentes do sistema, vamos observar tudo funcionando em tempo real. O monitoramento permite identificar gargalos e entender o comportamento do sistema sob carga.

Observe o sistema em ação: logs, disco e serviços ao vivo.

Ferramentas de monitoramento permitem identificar gargalos de CPU, memória, disco ou rede enquanto o sistema está em uso.

# Logs de autenticação (tente sudo errado em outro terminal)
sudo tail -f /var/log/auth.log    # ou sudo journalctl -f

# I/O de disco (Ctrl+C para sair)
iostat -xz 1 5

# Mensagens do kernel em tempo real
sudo dmesg -wT

# MONITORAMENTO COM WATCH - atualiza a cada 2 segundos
watch -n 2 'ps auxf | head -20'           # Processos (top 20)
watch -n 2 'ps auxf --sort=-%cpu | head -10'   # Processos ordenados por CPU (top 10)
watch -n 1 free -h                        # Memória em tempo real
watch -n 2 'df -h | grep -E "Filesystem|/$"' # Espaço em disco da partição raiz        

# Serviços com falha
systemctl --failed

# Serviços rodando (primeiros 15)
systemctl list-units --type=service --state=running | head -15
Relatório – Questão 9.1
Tente sudo com senha errada → qual mensagem no log (com timestamp)?

Questão 9.2
No iostat, o que indica %util alto ou await elevado? Gargalo no disco?
Questão 9.3
Durante o monitoramento, qual recurso parece ser o mais utilizado na sua máquina: CPU, memória ou disco? Justifique.

10. Hello World Web gerado pelo Terminal

O sistema operacional é a base para aplicações modernas, incluindo web. Neste módulo, veremos como criar e servir uma aplicação simples diretamente pelo terminal.

O SO é base para tudo — inclusive web. Crie HTML via Bash e sirva localmente.

O servidor Python utiliza sockets do sistema operacional para escutar conexões HTTP. Isso demonstra como aplicações web dependem diretamente dos serviços do sistema operacional.

cat <<EOF > so_web.html
<!DOCTYPE html>
<html lang="pt-br">
<head>
  <meta charset="UTF-8">
  <title>DEE355 - Hello Web</title>
  <style>
    body {
      background: #0d1117;
      color: #58a6ff;
      font-family: sans-serif;
      display: flex;
      justify-content: center;
      align-items: center;
      height: 100vh;
      margin: 0;
      text-align: center;
    }
    .card {
      border: 3px solid #79c0ff;
      padding: 3rem;
      border-radius: 15px;
      background: #161b22;
      max-width: 600px;
    }
    button {
      background: #58a6ff;
      color: #0d1117;
      border: none;
      padding: 1rem 2rem;
      font-size: 1.5rem;
      border-radius: 8px;
      cursor: pointer;
      margin-top: 1.5rem;
    }
    button:hover { background: #79c0ff; }
  </style>
</head>
<body>
  <div class="card">
    <h1>Olá do Linux!</h1>
    <p>Gerado via Bash - DEE355</p>
    <button onclick="document.querySelector('h1').innerText = 'JS rodando!'; alert('Evento JS!')">
      Clique para testar
    </button>
  </div>
</body>
</html>
EOF

# Servidor local (acesse http://localhost:8000/so_web.html)
python3 -m http.server 8000
Relatório – Questão 10.1
Abra a página e clique no botão. O que acontece? Como o JS altera o DOM?

Questão 10.2
Por que conseguimos criar e servir uma página web só com comandos do terminal?

Questão 10.3
Qual porta o servidor Python está utilizando? Como verificar isso usando um comando do Linux?

11. Sinais e Controle de Processos

Além de criar processos, o sistema operacional também permite controlá-los. Neste módulo, veremos como enviar sinais para pausar, interromper ou finalizar programas.

O Linux permite controlar processos através de sinais. Sinais são mensagens enviadas pelo sistema operacional para interromper, pausar ou finalizar processos em execução.

# Criar um processo em background (roda por 300 segundos)
sleep 300 &

# Listar jobs em background
jobs

# Ver PID do processo criado
ps aux | grep sleep

# Enviar sinal de término (SIGTERM)
kill [PID]

# Criar novamente o processo
sleep 300 &

# Forçar encerramento imediato (SIGKILL)
kill -9 [PID]

# Listar sinais disponíveis
kill -l

O sinal SIGTERM (padrão do kill) pede que o processo finalize de forma controlada. Já o SIGKILL força o encerramento imediato, sem permitir limpeza de recursos.

Relatório – Questão 11.1
Qual a diferença entre kill PID e kill -9 PID?

Questão 11.2
Após executar sleep 300 &, qual foi o PID do processo criado?

Questão 11.3
O que acontece se você pressionar Ctrl + C em um processo rodando no foreground? Qual sinal é enviado?

Questão 11.4
Qual a diferença entre executar um processo em foreground e background?

12. Threads e Execução Paralela

Enquanto processos executam programas isoladamente, threads permitem execução paralela dentro do mesmo processo. Vamos explorar como isso melhora desempenho e eficiência.

Muitos programas modernos utilizam threads para executar várias tarefas simultaneamente dentro de um único processo. Cada thread compartilha a mesma memória do processo principal, mas pode executar instruções de forma independente.

No Linux, podemos observar threads usando ferramentas como top, htop ou ps. Alguns programas (como navegadores ou servidores) utilizam dezenas ou centenas de threads para melhorar desempenho.

# Listar processos e threads
ps -eLf | head -20

# Visualizar threads de um processo específico
ps -T -p [PID]

# Monitor interativo mostrando threads
top -H

# No htop pressione:
# H  → mostrar threads
# F5 → visualização em árvore

Cada thread possui um identificador chamado TID (Thread ID), mas todas pertencem ao mesmo processo principal identificado pelo PID. Isso permite compartilhar memória e recursos do sistema.

Exemplo simples criando múltiplas threads (Python)

cat < threads.py
import threading
import time

def tarefa(id):
    for i in range(3):
        print(f"Thread {id} executando...")
        time.sleep(1)

threads = []

for i in range(5):
    t = threading.Thread(target=tarefa, args=(i,))
    threads.append(t)
    t.start()

for t in threads:
    t.join()

print("Todas as threads terminaram.")
EOF

python3 threads.py

Enquanto o programa executa, abra outro terminal e observe as threads usando:

ps -eLf | grep python
Relatório – Questão 12.1
Qual a diferença entre processo e thread?

Questão 12.2
Ao executar ps -eLf, quantas threads aparecem para o processo Python?

Questão 12.3
Por que programas como navegadores e servidores web utilizam múltiplas threads?

Questão 12.4
Qual a vantagem de threads compartilharem memória dentro do mesmo processo?

🧠 Módulo 13 — Memória Virtual e Paginação

Retornando ao tema da memória, agora aprofundamos em como o sistema operacional abstrai a memória física usando memória virtual e paginação.

📌 13.1 O que é Memória Virtual?

A memória virtual é uma técnica utilizada pelos sistemas operacionais para permitir que programas utilizem mais memória do que a disponível fisicamente na RAM. Ela cria a ilusão de um espaço de memória grande e contínuo para cada processo.

Principais Conceitos

🔍 Como o SO engana o processo: Quando um programa pede memória, o Kernel não entrega um endereço físico da RAM. Ele entrega um Endereço Virtual. A Unidade de Gerenciamento de Memória (MMU) do processador traduz esse endereço em tempo real. Se o dado não estiver na RAM, ocorre o Page Fault e o Kernel busca no Swap.

📌 13.2 Benefícios da Memória Virtual

📌 13.3 Paginação

A paginação divide a memória virtual em blocos chamados páginas e a memória física em blocos chamados quadros (frames).

📌 13.4 Tabela de Páginas

A tabela de páginas mantém o mapeamento entre os endereços virtuais e físicos. Cada processo possui sua própria tabela.

📌 13.5 Falta de Página (Page Fault)

Ocorre quando um processo tenta acessar uma página que não está na RAM. O sistema operacional então:

  1. Interrompe o processo
  2. Busca a página no disco
  3. Carrega na RAM
  4. Atualiza a tabela de páginas
  5. Retoma a execução

📌 13.6 Substituição de Páginas

Quando a memória RAM está cheia, o sistema precisa escolher uma página para remover. Alguns algoritmos comuns:

📌 13.7 Comandos Linux Relacionados


free -h
vmstat
top
htop
cat /proc/meminfo
    
free -h
vmstat 1 5
cat /proc/meminfo | grep -E "Mem|Swap|Cache"

📌 13.8 Exemplo Prático


free -h
    

Mostra uso de memória RAM e swap.


vmstat 1
    

Mostra estatísticas da memória virtual em tempo real.

📌 13.9 Swap

O swap é a área em disco usada como extensão da RAM. Quando a memória física está cheia, páginas menos utilizadas são movidas para o swap.

🎯 Exercícios

  1. Explique o que é memória virtual
  2. Qual a diferença entre página e frame?
  3. O que é page fault?
  4. Para que serve o swap?
  5. Execute o comando free -h e analise a saída
Questão 13.1
Qual a diferença entre memória física e memória virtual?

Questão 13.2
O que é um "page fault" e como o SO lida com ele?

Questão 13.3
No comando free -h, o que significa quando o Swap está sendo usado?

14. Comparação entre Sistemas de Arquivos

Após entender como dados são armazenados em disco, vamos analisar como o sistema operacional organiza esses dados através dos sistemas de arquivos.

Embora o ext4 seja o padrão no Linux, outros sistemas de arquivos oferecem recursos especializados para cenários específicos.

Sistema Recursos Principais Melhor para
ext4 Journaling, estável, padrão Uso geral, desktops
XFS Alto desempenho, arquivos grandes Servidores multimídia, bancos de dados
Btrfs Snapshots, compactação, checksums Sistemas que precisam de rollback
tmpfs Armazenamento em RAM Arquivos temporários de alto desempenho
# Descobrir apenas o UUID de uma partição específica
lsblk -dno UUID /dev/sda1

# Ver qual sistema de arquivos está montado em cada pasta
findmnt
# Identificar o sistema de arquivos de cada partição
lsblk -f

          #extrair UUID
          lsblk -dno UUID /dev/sda3
          
# Ver detalhes do sistema de arquivos
sudo blkid

📌 14.X Montagem automática com /etc/fstab

O arquivo /etc/fstab define quais sistemas de arquivos serão montados automaticamente durante a inicialização do sistema.

📌 Conceito importante: O fstab funciona como uma tabela de montagem persistente. Ele informa ao kernel e ao sistema quais dispositivos devem ser montados, onde e com quais opções.

# Visualizar o fstab
cat /etc/fstab

# Testar montagens sem reiniciar
sudo mount -a

📄 Estrutura do fstab


UUID=xxxx-xxxx   /mnt/dados   ext4   defaults   0   2

📌 Exemplo prático

# Criar diretório de montagem
sudo mkdir /mnt/teste

# Identificar UUID do disco
sudo blkid

# Editar fstab
sudo nano /etc/fstab

UUID=abcd-1234   /mnt/teste   ext4   defaults   0   2

Após salvar, execute:

sudo mount -a

Se não houver erro, a configuração está correta.

Questão 14.1
Além do ext4, qual outro sistema de arquivos está presente no seu sistema? (use lsblk -f)

Questão 14.2
Qual a diferença prática entre um sistema de arquivos com journaling (ext4, XFS) e um sem journaling?

Questão 14.3
O que acontece com os dados armazenados em /tmp após uma reinicialização? Por quê? Questão 14.4
Qual a função do arquivo /etc/fstab?

Questão 14.5
O que acontece se houver um erro no fstab durante a inicialização do sistema?

Questão 14.6
Por que é recomendado usar UUID ao invés de /dev/sda1?

15. RAID (Redundant Array of Independent Disks)

Em ambientes reais, um único disco não é suficiente. Neste módulo, exploramos como múltiplos discos podem ser combinados para melhorar desempenho e tolerância a falhas.

RAID é uma tecnologia que combina múltiplos discos físicos em uma única unidade lógica para melhorar desempenho, aumentar capacidade ou fornecer tolerância a falhas.

📌 Conceito importante: O RAID pode ser implementado de duas formas: RAID por hardware (controlador dedicado) ou RAID por software (gerenciado pelo sistema operacional, como mdadm no Linux). A escolha impacta desempenho, custo e recuperação em caso de falhas.

15.1 Níveis de RAID

RAID 0 — Striping

Requisito: Mínimo 2 discos

Capacidade: Soma de todos os discos

Tolerância a falhas: Nenhuma

Vantagem: Alto desempenho em leitura/escrita

Desvantagem: Falha em um disco = perda total dos dados

Uso típico: Dados temporários, cache, onde desempenho é crítico e backup existe

RAID 1 — Mirroring

Requisito: Mínimo 2 discos

Capacidade: 50% do total (disco menor)

Tolerância a falhas: Suporta falha de 1 disco

Vantagem: Alta segurança, leitura paralela

Desvantagem: Custo por GB mais alto

Uso típico: Sistemas operacionais, bancos de dados críticos

RAID 5 — Striping com Paridade

Requisito: Mínimo 3 discos

Capacidade: N-1 discos (1 disco para paridade)

Tolerância a falhas: Suporta falha de 1 disco

Vantagem: Bom equilíbrio entre capacidade, segurança e desempenho

Desvantagem: Reconstrução lenta, desempenho de escrita reduzido

Uso típico: Servidores de arquivos, armazenamento geral

RAID 6 — Striping com Paridade Dupla

Requisito: Mínimo 4 discos

Capacidade: N-2 discos (2 discos para paridade)

Tolerância a falhas: Suporta falha de 2 discos

Vantagem: Segurança adicional contra falhas simultâneas

Desvantagem: Menor capacidade útil, reconstrução mais lenta

Uso típico: Armazenamento de longo prazo, servidores críticos

RAID 10 — Mirror + Striping

Requisito: Mínimo 4 discos (pares espelhados em stripe)

Capacidade: 50% do total

Tolerância a falhas: Suporta falha de 1 disco por par espelhado

Vantagem: Alto desempenho + alta tolerância a falhas

Desvantagem: Custo elevado

Uso típico: Bancos de dados de alta performance, servidores críticos

RAID 50, 60 — Níveis Aninhados

Combinações de RAID 5/6 com RAID 0. Oferecem maior capacidade e desempenho em ambientes com muitos discos (8, 12, 16+). Usados em servidores empresariais e storage NAS/SAN.

15.2 Comparativo entre Níveis RAID

Nível Discos Mínimo Capacidade Útil Leitura Escrita Tolerância a Falhas
RAID 0 ≥ 2 100% ⬆️⬆️ Muito Alto ⬆️⬆️ Muito Alto ❌ Nenhuma
RAID 1 2 50% ⬆️ Alto ⬇️ Médio ✅ 1 disco
RAID 5 3 N-1 ⬆️ Alto ⬇️ Médio ✅ 1 disco
RAID 6 4 N-2 ⬆️ Alto ⬇️ Baixo ✅✅ 2 discos
RAID 10 4 50% ⬆️⬆️ Muito Alto ⬆️ Alto ✅ 1 disco por espelho

15.3 RAID por Software no Linux (mdadm)

O Linux possui suporte nativo a RAID via software através do mdadm (Multiple Device Admin). Esta ferramenta permite criar, gerenciar e monitorar arrays RAID sem necessidade de hardware especializado.

# Instalar o mdadm (se necessário)
sudo apt install mdadm

# Verificar discos disponíveis
lsblk

# Criar um RAID 1 (espelhamento) com dois discos
sudo mdadm --create /dev/md0 --level=1 --raid-devices=2 /dev/sdb1 /dev/sdc1

# Verificar o status do array
cat /proc/mdstat

# Ver detalhes do array
sudo mdadm --detail /dev/md0

# Criar sistema de arquivos no array RAID
sudo mkfs.ext4 /dev/md0

# Montar o array
sudo mount /dev/md0 /mnt/raid

# Simular falha de um disco
sudo mdadm --manage /dev/md0 --fail /dev/sdb1

# Remover disco com falha
sudo mdadm --manage /dev/md0 --remove /dev/sdb1

# Adicionar um novo disco ao array
sudo mdadm --manage /dev/md0 --add /dev/sdd1

# Parar um array RAID
sudo mdadm --stop /dev/md0

# Montar array após reinicialização
sudo mdadm --assemble --scan

📌 Monitoramento e Persistência: Para que o array seja reconhecido automaticamente após reinicializações, é necessário salvar a configuração:

sudo mdadm --detail --scan | sudo tee -a /etc/mdadm/mdadm.conf
sudo update-initramfs -u

15.4 RAID por Hardware vs. Software

🖥️ RAID por Hardware

  • Controlador dedicado com processador próprio
  • Melhor desempenho (não consome CPU)
  • Cache próprio com bateria (proteção contra queda)
  • Transparente para o SO (aparece como um único disco)
  • Maior custo (controlador RAID)
  • Recuperação depende do mesmo modelo de controlador

💾 RAID por Software (mdadm)

  • Implementado pelo sistema operacional
  • Consome CPU para cálculos (RAID 5/6 especialmente)
  • Mais flexível (qualquer combinação de discos)
  • Custo zero (apenas os discos)
  • Portável entre diferentes controladores
  • Recuperação possível em qualquer máquina Linux

15.5 RAID em Cenários Reais

📌 Exemplos práticos de uso:

15.6 Comandos de Monitoramento RAID

# Verificar status de todos os arrays
cat /proc/mdstat

# Ver detalhes completos de um array específico
sudo mdadm --detail /dev/md0

# Verificar discos com falhas ou problemas
sudo mdadm --detail /dev/md0 | grep -E "failed|spare"

# Verificar uso de disco e partições
lsblk -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINT

# Verificar logs relacionados a RAID
sudo journalctl | grep mdadm

# Monitorar reconstrução em tempo real
watch -n 1 'cat /proc/mdstat'

15.7 Exercícios Práticos

# 1. Verifique se há arrays RAID configurados no sistema
cat /proc/mdstat

# 2. Liste todos os discos e partições
lsblk -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINT

# 3. Se houver um array, veja seus detalhes
sudo mdadm --detail /dev/md0  # substitua md0 pelo nome do array

# 4. (Opcional - requer discos extras) Simule a criação de um RAID 1
# ATENÇÃO: Use discos de teste, não partições importantes!
Relatório – Módulo 15 – RAID

Questão 15.1
Explique a principal diferença entre RAID 0, RAID 1 e RAID 5 em termos de tolerância a falhas e capacidade útil.

Questão 15.2
Qual a diferença entre RAID por hardware e RAID por software? Quais as vantagens e desvantagens de cada um?

Questão 15.3
Se você tem 4 discos de 1 TB cada, qual seria a capacidade útil em RAID 5, RAID 6 e RAID 10?

Questão 15.4
Execute cat /proc/mdstat no seu sistema. Existe algum array RAID configurado? Se sim, qual nível e quais discos estão sendo utilizados?

Questão 15.5
Por que o RAID 5 é considerado "arriscado" com discos de grande capacidade (8 TB ou mais)? O que isso tem a ver com o tempo de reconstrução e a chance de uma segunda falha?

Questão 15.6
Um servidor com RAID 5 sofreu falha em um disco. Quais são os procedimentos necessários para recuperar a redundância após substituir o disco com falha?

Questão 15.7
RAID substitui a necessidade de backup? Justifique sua resposta.

Questão 15.8
Pesquise: O que é RAID de software via LVM (Logical Volume Manager) e como ele se diferencia do mdadm?

🔍 Para aprofundamento:

16. Permissões e Controle de Acesso

Além de armazenar dados, o sistema operacional precisa proteger informações. Neste módulo, veremos como funcionam permissões e controle de acesso no Linux.

O Linux é um sistema multiusuário desde sua concepção. O controle de acesso a arquivos, diretórios e recursos do sistema é fundamental para segurança e organização.

📌 Conceito importante: No Linux, tudo é arquivo — e cada arquivo pertence a um dono (owner) e a um grupo (group). As permissões definem quem pode ler, escrever ou executar cada arquivo. Além disso, mecanismos como sudo e arquivos de autenticação (/etc/passwd, /etc/shadow) gerenciam quem pode fazer o quê no sistema.

16.1 Modelo de Permissões Tradicional (UGO)

O modelo tradicional de permissões no Linux utiliza três níveis de acesso para três categorias de usuários:

User (U)

O dono do arquivo

Group (G)

Usuários do grupo dono

Others (O)

Demais usuários do sistema

Cada categoria pode ter três permissões:

r (read) — leitura: permite visualizar o conteúdo do arquivo ou listar diretório

w (write) — escrita: permite modificar o arquivo ou criar/excluir arquivos no diretório

x (execute) — execução: permite executar o arquivo (programa) ou acessar o diretório (cd)

16.2 Visualizando Permissões

# Listar arquivos com permissões
ls -l

# Exemplo de saída:
# -rw-r--r-- 1 aluno alunos 1024 Jan 15 10:30 arquivo.txt
# drwxr-x--- 2 aluno alunos 4096 Jan 15 10:30 pasta/

# Explicação do primeiro campo:
# [tipo][owner perms][group perms][others perms]
# - = arquivo comum | d = diretório | l = link simbólico
# rwx = leitura, escrita, execução
# r-x = leitura e execução (sem escrita)
# r-- = apenas leitura

# Ver permissões em formato octal (numérico)
stat -c "%a %n" arquivo.txt

# Ver apenas as permissões de um arquivo
ls -l arquivo.txt | awk '{print $1}'

16.3 Alterando Permissões (chmod)

O comando chmod (change mode) altera permissões de arquivos e diretórios. Pode ser usado com notação simbólica ou octal.

# NOTAÇÃO SIMBÓLICA
# Dar permissão de execução para o dono
chmod u+x arquivo.sh

# Remover permissão de escrita do grupo
chmod g-w documento.txt

# Dar permissão total para dono, leitura/execução para grupo, nenhuma para outros
chmod u=rwx,g=rx,o=--- script.py

# Adicionar permissão de escrita para todos
chmod a+w arquivo.txt

# NOTAÇÃO OCTAL (NUMÉRICA)
# 4 = read, 2 = write, 1 = execute
# 7 = 4+2+1 (rwx), 6 = 4+2 (rw-), 5 = 4+1 (r-x), 4 = r--, 0 = ---

chmod 755 script.sh      # dono: rwx, grupo: r-x, outros: r-x
chmod 644 arquivo.txt    # dono: rw-, grupo: r--, outros: r--
chmod 600 senhas.txt     # dono: rw-, grupo: ---, outros: ---
chmod 700 pasta_privada  # apenas dono tem acesso total

# Modo recursivo (aplica a diretórios e subdiretórios)
chmod -R 755 pasta/

📌 Tabela de Permissões em Octal:

OctalBinárioPermissãoDescrição
0000---Nenhuma permissão
1001--xApenas execução
2010-w-Apenas escrita
3011-wxEscrita e execução
4100r--Apenas leitura
5101r-xLeitura e execução
6110rw-Leitura e escrita
7111rwxLeitura, escrita e execução

16.4 Alterando Dono e Grupo (chown, chgrp)

# Alterar o dono do arquivo
sudo chown maria arquivo.txt

# Alterar o grupo do arquivo
sudo chgrp desenvolvedores projeto/

# Alterar dono e grupo simultaneamente
sudo chown maria:desenvolvedores projeto/

# Alterar recursivamente
sudo chown -R maria:desenvolvedores pasta_projeto/

# Verificar alterações
ls -l pasta_projeto/

16.5 Permissões Especiais (SUID, SGID, Sticky Bit)

Além das permissões básicas, o Linux possui três bits especiais que alteram o comportamento padrão:

SUID (4)

Set User ID — ao executar, o programa assume os privilégios do dono, não do usuário que o executa. Ex: /usr/bin/passwd (precisa de acesso a /etc/shadow)

chmod u+s arquivo chmod 4755 arquivo

SGID (2)

Set Group ID — em arquivos, executa com permissões do grupo dono. Em diretórios, novos arquivos herdam o grupo do diretório.

chmod g+s diretorio chmod 2755 diretorio

Sticky Bit (1)

Sticky Bit — em diretórios, apenas o dono do arquivo pode deletá-lo (mesmo que outros tenham permissão de escrita). Ex: /tmp

chmod +t diretorio chmod 1777 diretorio
# Verificar bits especiais (letra minúscula = ativo, maiúscula = inativo)
ls -l /usr/bin/passwd
# -rwsr-xr-x 1 root root → 's' no lugar do 'x' indica SUID ativo

ls -ld /tmp
# drwxrwxrwt → 't' no lugar do 'x' indica Sticky Bit ativo

# Aplicar SUID em um script (apenas para binários, não scripts shell)
sudo chmod u+s /usr/local/bin/meu_programa

# Aplicar SGID em diretório
sudo chmod g+s /compartilhado

# Aplicar Sticky Bit
sudo chmod +t /compartilhado_temp

16.6 ACLs (Access Control Lists)

As ACLs permitem definir permissões mais granulares que o modelo tradicional, permitindo especificar permissões para usuários e grupos específicos além do dono/grupo/outros.

# Instalar suporte a ACL (se necessário)
sudo apt install acl

# Verificar ACLs atuais
getfacl arquivo.txt

# Definir ACL para um usuário específico
setfacl -m u:joao:rwx pasta/

# Definir ACL para um grupo específico
setfacl -m g:desenvolvedores:rx documento.txt

# Remover ACL de um usuário
setfacl -x u:joao pasta/

# Remover todas as ACLs
setfacl -b pasta/

# Copiar ACLs de um arquivo para outro
getfacl arquivo1.txt | setfacl --set-file=- arquivo2.txt

# Verificar se partição suporta ACL (opção acl no mount)
mount | grep acl

16.7 Gerenciamento de Usuários e Autenticação

O Linux armazena informações de usuários em arquivos de texto e utiliza mecanismos de autenticação para controlar o acesso.

# Arquivos de autenticação
cat /etc/passwd      # Informações básicas dos usuários (UID, shell, home)
cat /etc/shadow      # Senhas criptografadas (apenas root pode ler)
cat /etc/group       # Grupos do sistema
cat /etc/sudoers     # Quem pode usar sudo (editar com visudo!)

# Gerenciar usuários
sudo useradd -m -s /bin/bash joao      # Criar usuário com home e shell
sudo passwd joao                        # Definir senha
sudo usermod -aG sudo joao              # Adicionar ao grupo sudo
sudo userdel -r joao                    # Remover usuário e seu home

# Gerenciar grupos
sudo groupadd desenvolvedores
sudo usermod -aG desenvolvedores maria
groups maria                             # Ver grupos do usuário
sudo groupdel desenvolvedores

# Informações do usuário atual
whoami                                   # Nome do usuário
id                                       # UID, GID e grupos
id joao                                  # Informações de outro usuário

📌 Estrutura do /etc/passwd: username:password:UID:GID:comment:home:shell
O campo password atualmente contém 'x', indicando que a senha está no /etc/shadow (mais seguro).

📌 Estrutura do /etc/shadow: username:senha_criptografada:ultima_alteracao:min:max:aviso:inativo:expiracao
Apenas root tem acesso de leitura a este arquivo.

16.8 Sudo e Privilégios Elevados

O sudo permite que usuários autorizados executem comandos com privilégios de root (ou outros usuários) sem precisar da senha do root.

# Verificar privilégios sudo do usuário atual
sudo -l

# Executar comando como root
sudo comando

# Executar comando como outro usuário
sudo -u maria comando

# Abrir shell como root (cuidado!)
sudo -i

# Editar o arquivo sudoers (NUNCA editar diretamente!)
sudo visudo

# Exemplo de linha no /etc/sudoers:
# joao ALL=(ALL:ALL) ALL                    # joao pode tudo com sudo
# maria ALL=(ALL) /usr/bin/apt, /usr/bin/systemctl  # apenas comandos específicos
# %desenvolvedores ALL=(ALL) NOPASSWD: ALL   # grupo sem pedir senha

16.9 Exercícios Práticos

# 1. Crie um arquivo e visualize suas permissões
touch teste.txt
ls -l teste.txt

# 2. Altere as permissões para que apenas o dono possa ler e escrever
chmod 600 teste.txt

# 3. Crie um diretório compartilhado com SGID
mkdir /tmp/compartilhado
sudo chown :desenvolvedores /tmp/compartilhado
sudo chmod 2770 /tmp/compartilhado
ls -ld /tmp/compartilhado

# 4. Adicione um usuário de teste
sudo useradd -m testuser
sudo passwd testuser

# 5. Verifique as informações do novo usuário
id testuser
ls -la /home/testuser

# 6. Configure uma ACL para permitir acesso a outro usuário
setfacl -m u:testuser:rx teste.txt
getfacl teste.txt

# 7. (Opcional) Remova o usuário de teste
sudo userdel -r testuser
Relatório – Módulo 16 – Permissões e Controle de Acesso

Questão 16.1
Explique o significado de cada caractere na permissão -rwxr-x---. Quem pode ler, escrever e executar este arquivo?

Questão 16.2
Qual a diferença entre chmod 755 e chmod 4755? O que o bit SUID faz?

Questão 16.3
Por que o diretório /tmp possui permissão drwxrwxrwt? Qual a função do sticky bit?

Questão 16.4
Execute ls -l /usr/bin/passwd e explique por que este arquivo possui o bit SUID ativo.

Questão 16.5
Qual a diferença entre os arquivos /etc/passwd e /etc/shadow? Por que as senhas são armazenadas separadamente?

Questão 16.6
O que acontece se um diretório tem permissão de escrita (w) mas não tem permissão de execução (x)? Explique.

Questão 16.7
Como você adicionaria um usuário ao grupo sudo para que ele possa executar comandos administrativos?

Questão 16.8
Para que serve o comando visudo? Qual o risco de editar o arquivo /etc/sudoers diretamente?

Questão 16.9
Crie um arquivo com permissão 640 e propriedade aluno:professores. Quem pode ler este arquivo? Quem pode escrever?

Questão 16.10
Pesquise: O que são ACLs (Access Control Lists) e em que situação elas são mais úteis que o modelo tradicional de permissões?

🔍 Comandos úteis para revisão:

17. Gerenciamento de Pacotes e Software

Para utilizar software no sistema, é necessário instalá-lo e gerenciá-lo. Neste módulo, exploramos como o Linux gerencia pacotes e dependências.

Todo programa que você usa no Linux foi instalado de alguma forma. Entender como o sistema gerencia software é essencial para qualquer administrador ou desenvolvedor Linux.

No Linux, software é distribuído em pacotes — arquivos compactados contendo o programa, bibliotecas e metadados de dependências. O gerenciador de pacotes automatiza instalação, atualização e remoção, resolvendo dependências automaticamente.

📌 Conceito importante: Um repositório é um servidor que armazena pacotes verificados e assinados digitalmente. Quando você executa apt install firefox, o sistema consulta a lista de repositórios em /etc/apt/sources.list, baixa o pacote e suas dependências, verifica a assinatura criptográfica e só então instala. Isso garante autenticidade e integridade do software.

17.1 APT — Gerenciador de Pacotes do Debian/Ubuntu

# Ver de onde vêm os programas — lista de repositórios
cat /etc/apt/sources.list
ls /etc/apt/sources.list.d/

# Atualizar a lista de pacotes disponíveis (não instala nada)
sudo apt update

# Ver quantos pacotes estão disponíveis
apt list 2>/dev/null | wc -l

# Buscar um pacote pelo nome ou descrição
apt search htop
apt search "monitor de sistema"

# Ver detalhes de um pacote (versão, tamanho, dependências)
apt show htop
apt show firefox

# Instalar um pacote
sudo apt install htop

# Remover pacote (mantém arquivos de configuração)
sudo apt remove htop

# Remover pacote + configurações
sudo apt purge htop

# Atualizar todos os pacotes do sistema
sudo apt upgrade

# Remover pacotes órfãos (dependências que não são mais necessárias)
sudo apt autoremove

# Ver histórico de instalações
cat /var/log/apt/history.log | head -40

17.2 dpkg — O Gerenciador de Baixo Nível

O apt é uma interface amigável sobre o dpkg, que é o gerenciador real de pacotes .deb. Enquanto o apt resolve dependências automaticamente, o dpkg opera diretamente nos arquivos de pacote.

# Listar todos os pacotes instalados
dpkg -l | head -20

# Contar quantos pacotes estão instalados
dpkg -l | grep "^ii" | wc -l

# Ver arquivos instalados por um pacote específico
dpkg -L bash

# Descobrir a qual pacote um arquivo pertence
dpkg -S /usr/bin/python3
dpkg -S /bin/ls

# Ver informações de um pacote instalado
dpkg -s firefox

# Instalar um .deb baixado manualmente
# sudo dpkg -i nome_do_pacote.deb

# Ver pacotes com problemas
dpkg -l | grep -E "^(rc|iF|iU)"

📌 Legenda do dpkg -l:

CódigoSignificado
iiInstalado e funcionando normalmente
rcRemovido, mas arquivos de configuração ainda presentes
unDesconhecido / não instalado
iFInstalado, mas com falha

17.3 Compilação a partir do Código Fonte

Antes dos gerenciadores de pacotes, todo software era compilado manualmente. Ainda hoje isso é necessário quando o pacote não existe no repositório, quando se precisa de uma versão específica ou quando se quer otimizações para o hardware local. O fluxo clássico é: configurar → compilar → instalar.

# Instalar ferramentas de compilação (gcc, make, etc.)
sudo apt install build-essential

# Fluxo clássico de compilação a partir do fonte:

# 1. Baixar o código fonte (exemplo com o htop)
wget https://github.com/htop-dev/htop/releases/download/3.3.0/htop-3.3.0.tar.xz

# 2. Extrair o arquivo
tar -xf htop-3.3.0.tar.xz
cd htop-3.3.0/

# 3. Verificar dependências e configurar para o sistema atual
#    (gera o Makefile adaptado ao ambiente)
./configure

# 4. Compilar (usa todos os núcleos disponíveis com -j)
make -j$(nproc)

# 5. Instalar no sistema
sudo make install

# 6. Verificar onde foi instalado
which htop

# Alternativa moderna: cmake (usado por projetos mais novos)
# cmake -B build && cmake --build build && sudo cmake --install build

📌 Por que ./configure existe? O script configure inspeciona o sistema — verifica qual compilador está disponível, quais bibliotecas estão instaladas e onde estão os headers. Com isso, gera um Makefile personalizado para aquela máquina. Um mesmo código fonte pode compilar em Linux, macOS e BSD graças a esse mecanismo.

17.4 Formatos Modernos de Distribuição

Pacotes tradicionais (.deb, .rpm) dependem das bibliotecas do sistema. Formatos modernos resolvem isso empacotando todas as dependências junto com o aplicativo, garantindo que o mesmo pacote rode em qualquer distribuição Linux.

Flatpak

Sandbox: Isolamento total do sistema

Repositório principal: Flathub

Dependências: Compartilhadas via runtimes

Atualização: Automática e delta (baixa só o que mudou)

Preferido no GNOME/Fedora. Foco em segurança e sandboxing.

Snap

Sandbox: Confinamento por AppArmor

Repositório: Snap Store (Canonical)

Dependências: Totalmente embutidas no pacote

Atenção: Pacotes maiores, startup mais lento

Criado pela Canonical. Padrão no Ubuntu para alguns apps.

AppImage

Sandbox: Nenhuma (roda como arquivo comum)

Instalação: Nenhuma — é portátil como um .exe

Dependências: Totalmente embutidas

Uso: chmod +x app.AppImage && ./app.AppImage

Ideal para distribuir um único binário sem instalar nada.

RPM / DNF (Red Hat / Fedora)

Distros: Fedora, RHEL, CentOS, openSUSE

Baixo nível: rpm -ivh pacote.rpm

Alto nível: dnf install pacote

Equivalente ao: dpkg/apt no Debian

O outro grande ecossistema de pacotes Linux, além do .deb.
# FLATPAK
sudo apt install flatpak                        # instalar suporte
flatpak remote-add --if-not-exists flathub \
    https://dl.flathub.org/repo/flathub.flatpakrepo
flatpak install flathub org.videolan.VLC        # instalar app
flatpak list                                    # listar instalados
flatpak update                                  # atualizar tudo

# SNAP
snap list                                       # listar snaps instalados
sudo snap install vlc                           # instalar
sudo snap remove vlc                            # remover
snap info vlc                                   # detalhes do pacote

# APPIMAGE
wget https://exemplo.com/app.AppImage           # baixar
chmod +x app.AppImage                           # tornar executável
./app.AppImage                                  # executar diretamente

# Ver qual formato um programa foi instalado
which firefox
dpkg -S $(which firefox) 2>/dev/null || echo "Pode ser snap/flatpak"
snap list | grep firefox
flatpak list | grep firefox
Relatório – Módulo 17 – Gerenciamento de Pacotes

Questão 17.1
Execute dpkg -l | grep "^ii" | wc -l. Quantos pacotes estão instalados na sua máquina? O que o prefixo ii significa?

Questão 17.2
Use dpkg -S /bin/ls. A qual pacote pertence o comando ls? O que isso revela sobre a organização do software no Linux?

Questão 17.3
Qual a diferença entre apt remove e apt purge? Em qual situação usar cada um?

Questão 17.4
Explique o papel de cada etapa da compilação a partir do fonte: ./configure, make e make install. Por que ainda compilamos do fonte se existem repositórios prontos?

Questão 17.5
Qual a diferença principal entre Flatpak, Snap e AppImage? Em qual cenário cada formato é mais adequado?

Questão 17.6
Execute cat /var/log/apt/history.log | head -40. O que é possível descobrir sobre a história de instalações do sistema?

Questão 17.7
Pesquise: O que é o arquivo /etc/apt/sources.list? Qual a diferença entre um repositório main, universe e multiverse no Ubuntu?

🔍 Comparativo rápido dos gerenciadores:

Ação Debian/Ubuntu (apt) Fedora/RHEL (dnf) Arch (pacman)
Instalar apt install pkg dnf install pkg pacman -S pkg
Remover apt remove pkg dnf remove pkg pacman -R pkg
Buscar apt search pkg dnf search pkg pacman -Ss pkg
Atualizar tudo apt upgrade dnf upgrade pacman -Syu
Listar instalados dpkg -l rpm -qa pacman -Q

18. 🐧 Kernel e Módulos do Linux

Por fim, chegamos ao núcleo do sistema operacional: o kernel. Ele é responsável por coordenar todos os recursos que estudamos ao longo da prática.

O kernel Linux é modular por design. Nem todos os drivers e funcionalidades precisam estar compilados diretamente no kernel (monolítico). Muitos são carregados dinamicamente como módulos, o que torna o sistema mais flexível, leve e fácil de manter.

📌 Conceito importante: Um módulo do kernel é um pedaço de código que pode ser carregado ou descarregado em tempo de execução sem reiniciar o sistema. Eles são usados principalmente para drivers de hardware (placa de rede, vídeo, USB, Wi-Fi, impressoras, etc.), sistemas de arquivos e funcionalidades de segurança.

Nota: O comando modprobe -r falhará se o hardware estiver sendo utilizado ativamente pelo sistema.

18.1 Comandos para Gerenciar Módulos

# Listar todos os módulos carregados no kernel
lsmod

# Mostrar módulos com mais detalhes (tamanho, uso, dependências)
lsmod | head -20

#módulos de vídeo
lsmod | grep video

# Ver informações detalhadas de um módulo específico
modinfo snd_hda_intel    # exemplo: driver de áudio
modinfo vboxsf           # exemplo: VirtualBox Shared Folders

# Carregar um módulo manualmente
sudo modprobe usb_storage

# Remover um módulo (se não estiver em uso)
sudo modprobe -r usb_storage

# Inserir módulo diretamente (menos recomendado)
# sudo insmod /caminho/do/modulo.ko

# Ver quais módulos estão disponíveis no sistema
find /lib/modules/$(uname -r) -type f -name "*.ko" | wc -l

📌 Diferença importante:

18.2 Parâmetros de Boot e Kernel Command Line

O kernel recebe parâmetros durante a inicialização através do GRUB. Esses parâmetros podem alterar o comportamento do sistema sem recompilar o kernel.

# Ver os parâmetros com que o kernel atual foi inicializado
cat /proc/cmdline

# Exemplo de saída típica:
# BOOT_IMAGE=/vmlinuz-6.5.0-35-generic root=/dev/sda3 ro quiet splash vt.handoff=7

Parâmetros comuns úteis:

18.3 Explorando o Kernel Atual

# Versão completa do kernel em execução
uname -a

# Ver a versão do kernel e diretório de módulos
uname -r

# Listar todos os módulos disponíveis para esta versão do kernel
ls /lib/modules/$(uname -r)/

# Ver configurações com que o kernel foi compilado
cat /boot/config-$(uname -r) | grep -E "CONFIG_MODULE|CONFIG_DEBUG" | head -15
Relatório – Questão 18.1
Execute lsmod | wc -l. Quantos módulos estão carregados no seu kernel?

Questão 18.2
Escolha um módulo relacionado a hardware (ex: rede, áudio, USB ou vídeo) e execute modinfo nome_do_modulo. O que você consegue descobrir sobre ele?

Questão 18.3
Qual o conteúdo do arquivo /proc/cmdline? Explique o significado de pelo menos dois parâmetros que aparecem.

Questão 18.4
Por que é vantajoso o kernel Linux ser modular em vez de totalmente monolítico?

Conceitos de Sistemas Operacionais Observados

Durante esta prática, você interagiu diretamente com vários mecanismos internos do sistema operacional Linux.

Questionário Final – Relatório Prático (para entrega)

Responda às questões abaixo com base no que observou ao executar os comandos. Inclua prints ou trechos relevantes quando solicitado. Organize por número da questão.

Módulo 1 – Hardware e Kernel
1.1 Localize a flag vmx ou svm. O que ela indica sobre virtualização?
1.2 Qual a linha completa do uname -a (versão do kernel e data de compilação)?
1.3 O diretório /proc ocupa espaço em disco? Explique.

Módulo 2 – Memória e Swap
2.1 Total de RAM instalada e valor de Mem: available no free -h?
2.2 Ao abrir abas pesadas, si e so aumentaram no vmstat? O que isso significa para o desempenho?
2.3 Por que a memória "used" pode ser alta mesmo com poucos programas abertos? Explique o papel do cache.

Módulo 3 – Processos e Carga
3.1 No htop, o que muda ao pressionar H? Por quê?
3.2 Por que navegadores modernos aparecem com dezenas de processos (multi-process architecture)?
3.3 Existe algum processo no estado "sleeping"? O que isso significa?

Módulo 4 – Logs do Sistema
4.1 Alguma mensagem recente interessante no dmesg -T ou journalctl -xe?
4.2 Qual a diferença entre dmesg e journalctl? Qual deles mostra apenas mensagens do kernel?

Módulo 5 – Armazenamento e Barramentos
5.1 Espaço usado/total da partição raiz (/) no df -h?
5.2 Algum dispositivo USB listado no lsusb? Qual?
5.3 O que são inodes? O sistema pode ficar cheio mesmo com espaço livre em disco?

Módulo 6 – Criação Multi-Linguagem
6.1 Diferença de execução entre programas interpretados (Python/Perl) e compilados (C)?
6.2 Qual a diferença entre executar um script Bash com bash hello.sh ou ./hello.sh?
6.3 Cada execução de um programa cria um PID diferente? O que isso indica sobre criação de processos?

Módulo 7 – Interfaces Gráficas via Terminal (Zenity)
7.1 O que acontece se o pacote zenity não estiver instalado?
7.2 Como o comando zenity se relaciona com system calls e bibliotecas gráficas?

Módulo 8 – Rede e Conectividade
8.1 Existe serviço em LISTEN nas portas 22 (SSH), 80 ou 443? Qual processo e PID?
8.2 Qual o IP da interface principal no ip addr?
8.3 Qual foi a latência média observada no comando ping?

Módulo 9 – Monitoramento em Tempo Real
9.1 Mensagem gerada ao tentar sudo com senha errada (inclua timestamp)?
9.2 No iostat, o que indica %util alto ou await elevado? Isso representa gargalo no disco?
9.3 Durante o monitoramento, qual recurso parece ser o mais utilizado na sua máquina (CPU, memória ou disco)? Justifique.

Módulo 10 – Hello World Web
10.1 Ao clicar no botão da página gerada, o que acontece? Como o JavaScript altera o DOM?
10.2 Por que conseguimos criar e servir uma página web apenas com comandos do terminal?
10.3 Qual porta o servidor Python está utilizando? Como verificar com um comando?

Módulo 11 – Sinais e Controle de Processos
11.1 Qual a diferença entre kill PID e kill -9 PID?
11.2 Qual sinal é enviado quando pressionamos Ctrl + C em um processo em foreground?
11.3 Qual a diferença entre executar um processo em foreground e em background?

Módulo 12 – Threads e Execução Paralela
12.1 Qual a diferença entre processo e thread?
12.2 Ao executar o script de threads em Python, quantas threads aparecem no ps -eLf?
12.3 Por que programas como navegadores e servidores web utilizam múltiplas threads?

Módulo 14 – Comparação entre Sistemas de Arquivos
14.1 Além do ext4, qual outro sistema de arquivos aparece no seu sistema (use lsblk -f)?
14.2 O que acontece com os arquivos em /tmp após uma reinicialização? Por quê?

Módulo 15 – RAID
15.1 Explique a principal diferença entre RAID 0, RAID 1 e RAID 5 (tolerância a falhas e capacidade).
15.2 Qual a diferença entre RAID por hardware e RAID por software (mdadm)?
15.3 Execute cat /proc/mdstat. Existe algum array RAID configurado no seu sistema?
15.4 RAID substitui a necessidade de backup? Justifique.

Módulo 16 – Permissões e Controle de Acesso
16.1 Explique o significado da permissão -rwxr-x---.
16.2 Qual a função do Sticky Bit no diretório /tmp?
16.3 Por que o arquivo /usr/bin/passwd possui o bit SUID?
16.4 Qual a diferença entre os arquivos /etc/passwd e /etc/shadow?

Módulo 17 – Gerenciamento de Pacotes
17.1 Quantos pacotes estão instalados no sistema (dpkg -l | grep "^ii" | wc -l)?
17.2 A qual pacote pertence o comando ls (dpkg -S /bin/ls)?
17.3 Qual a diferença entre apt remove e apt purge?
17.4 Qual a diferença entre Flatpak, Snap e AppImage?

Módulo 18 – Kernel e Módulos
18.1 Quantos módulos estão carregados no kernel (lsmod | wc -l)?
18.2 Escolha um módulo de hardware (ex: rede, áudio ou USB) e execute modinfo nome_do_modulo. O que você descobriu?
18.3 Qual o conteúdo do arquivo /proc/cmdline? Explique o significado de pelo menos dois parâmetros.
18.4 Por que é vantajoso o kernel Linux ser modular em vez de totalmente monolítico?

Entrega: Envie o relatório com suas respostas + prints das saídas mais relevantes no UFPR Virtual.
Boa exploração do sistema operacional!

🔑 Índice de Conceitos Chave

Principais conceitos explorados nesta prática:

/proc filesystem — Janela para o estado interno do kernel
Memória Virtual e Paginação — Como o SO abstrai a memória física
Processos vs Threads — Diferença fundamental de execução
Sinais (Signals) — Comunicação entre processos e kernel
Módulos do Kernel — Drivers carregados dinamicamente
RAID Levels — Balanceamento entre desempenho, capacidade e redundância
Permissões UGO + ACLs + Bits Especiais — Modelo de segurança Linux
Systemd e journalctl — Gerenciamento moderno de serviços e logs
Gerenciadores de pacotes (apt/dpkg) — Instalação e dependências
Namespaces e cgroups — Base tecnológica de containers (Docker/Podman)

Terminal Linux Simulado

Este é um terminal Linux simulado executado diretamente no navegador. Ele não executa comandos reais no sistema, mas reproduz saídas típicas para fins didáticos. Use-o para testar alguns comandos apresentados nesta prática, para verificar, use o help.

student@linux:~$

💡 Este terminal acima é apenas uma simulação didática. Se quiser experimentar um Linux real rodando no navegador, visite: WebVM – Linux no navegador . Ele executa uma máquina virtual Linux simulada diretamente no browser, permitindo rodar alguns comandos.