A entrada e saída (I/O) é um conceito fundamental em sistemas operacionais, responsável pela comunicação entre o computador e o mundo exterior, incluindo dispositivos, arquivos e outros sistemas. Esta disciplina explora como os sistemas gerenciam operações de I/O de forma eficiente.
Neste material, exploramos os conceitos de I/O através de exemplos práticos em três contextos diferentes:
Comandos Linux (Terminal) - Demonstrando manipulação de I/O diretamente no shell
Shell Script - Automatizando tarefas de I/O usando scripts
Python - Implementando operações de I/O de forma programática
Ao final deste módulo, você compreenderá como os sistemas operacionais gerenciam operações de entrada e saída e será capaz de implementar soluções eficientes de I/O em diferentes contextos.
Comandos Linux (Terminal)
Explorando operações de I/O através do terminal
Os comandos no Linux são úteis para demonstrar como o sistema gerencia I/O em arquivos, dispositivos e processos.
Leitura de arquivos (entrada)
Bash
cat arquivo.txt
O comando cat lê o conteúdo de arquivo.txt (entrada do sistema de arquivos) e o exibe no terminal (saída padrão, stdout).
Escrita em arquivos (saída)
Bash
echo "Texto de exemplo" > arquivo.txt
Redireciona a saída do comando echo para o arquivo arquivo.txt, sobrescrevendo seu conteúdo. Usa o operador > para saída.
Redirecionamento de entrada
Bash
sort < arquivo.txt
O comando sort lê o conteúdo de arquivo.txt como entrada (stdin) e ordena as linhas, exibindo no terminal.
Pipes (conexão de I/O entre processos)
Bash
ls -l | grep ".txt"
A saída do comando ls -l (lista de arquivos) é enviada como entrada para o comando grep, que filtra linhas contendo ".txt". Isso ilustra I/O entre processos.
Leitura de dispositivos de I/O
Bash
dd if=/dev/zero of=saida.bin bs=1M count=10
O comando dd lê do dispositivo /dev/zero (fonte de bytes nulos) e escreve 10 MB em saida.bin. Demonstra I/O em dispositivos.
Monitoramento de I/O
Bash
iostat
Exibe estatísticas de I/O do sistema, como taxa de leitura/escrita em discos, útil para analisar desempenho.
Shell Script
Automatizando tarefas de I/O com scripts
Scripts em shell podem combinar comandos Linux para automatizar tarefas de I/O, como leitura, escrita e manipulação de dados.
Script que lê um arquivo, processa e escreve em outro
Bash
#!/bin/bash
input_file="entrada.txt"
output_file="saida.txt"
# Lê o arquivo de entrada e filtra linhas com a palavra "teste"
grep "teste" $input_file > $output_file
# Conta o número de linhas processadas
echo "Linhas processadas: $(wc -l < $output_file)"
O script lê entrada.txt, filtra linhas contendo "teste" e escreve em saida.txt. O comando wc -l conta as linhas do arquivo de saída, ilustrando I/O com arquivos e redirecionamento.
Monitoramento de escrita em disco
Bash
#!/bin/bash
echo "Escrevendo 100 MB em um arquivo..."
dd if=/dev/zero of=teste.bin bs=1M count=100
echo "Tamanho do arquivo criado: $(ls -lh teste.bin | awk '{print $5}')"
Demonstra escrita em disco com dd e exibe o tamanho do arquivo gerado, simulando operações de I/O intensivas.
Python
Implementando operações de I/O de forma programática
Python é ideal para ilustrar I/O de forma programática, manipulando arquivos, dispositivos e até sockets para comunicação.
Leitura e escrita de arquivos
Python
# Leitura de um arquivo
with open('entrada.txt', 'r') as arquivo_entrada:
conteudo = arquivo_entrada.read()
print("Conteúdo lido:", conteudo)
# Escrita em um arquivo
with open('saida.txt', 'w') as arquivo_saida:
arquivo_saida.write("Texto escrito via Python\n")
Usa as funções open(), read() e write() para realizar I/O em arquivos. O modo 'r' é para leitura e 'w' para escrita.
Processamento linha a linha (I/O eficiente)
Python
with open('entrada.txt', 'r') as entrada:
with open('saida.txt', 'w') as saida:
for linha in entrada:
if 'teste' in linha:
saida.write(linha)
Lê entrada.txt linha a linha (evitando carregar o arquivo inteiro na memória) e escreve apenas as linhas com "teste" em saida.txt. Demonstra I/O otimizado.
Leitura de dispositivo (exemplo com /dev/urandom)
Python
with open('/dev/urandom', 'rb') as dispositivo:
dados = dispositivo.read(1024) # Lê 1 KB de dados aleatórios
print("Bytes lidos:", len(dados))
Lê dados do dispositivo /dev/urandom, que gera bytes aleatórios. Ilustra I/O com dispositivos em Python.
Conceitos Ilustrados
Visão teórica e visual das operações de entrada e saída
Em sistemas operacionais, os conceitos de buffer, drivers, chamadas de sistema e escalonamento de I/O são fundamentais para entender como os dispositivos interagem com o kernel.
Buffers: Memória intermediária para melhorar a eficiência de I/O.
Drivers: Interface entre o SO e o hardware de I/O.
Chamadas de sistema: Solicitações feitas por programas ao kernel para realizar I/O.
Escalonamento de I/O: Técnicas como FCFS, SSTF e SCAN otimizam a ordem de acesso aos discos.
Exemplos Avançados de Entrada e Saída
Casos práticos em bash, shell script e Python
1. Comandos Linux para operações de E/S
# Criar um arquivo e escrever nele
echo "Conteúdo de exemplo" > arquivo.txt
# Ler o conteúdo de um arquivo
cat arquivo.txt
# Copiar um arquivo (E/S de disco)
cp arquivo.txt arquivo_copia.txt
# Monitorar operações de E/S em tempo real
sudo iotop -o
# Redirecionar saída para um arquivo
ls -l > lista_arquivos.txt
# Redirecionar erro para um arquivo
comando_inexistente 2> erro.log
# Usar pipe para redirecionar entre processos
cat arquivo.txt | grep "exemplo"
# Listar discos e partições
lsblk
# Monitorar estatísticas de E/S
iostat -d 1
2. Shell Script para operações de E/S
#!/bin/bash
arquivo_entrada="dados.txt"
arquivo_saida="resultado.txt"
if [ -f "$arquivo_entrada" ]; then
echo "Processando $arquivo_entrada..."
grep "sucesso" "$arquivo_entrada" > "$arquivo_saida"
echo "Resultado salvo em $arquivo_saida"
else
echo "Erro: $arquivo_entrada não encontrado!" >&2
exit 1
fi
3. Python para operações de E/S
# Escrever em um arquivo
with open("exemplo.txt", "w") as arquivo:
arquivo.write("Dados de exemplo\n")
# Ler de um arquivo
with open("exemplo.txt", "r") as arquivo:
conteudo = arquivo.read()
print(conteudo)
import serial
# Comunicação serial
ser = serial.Serial('/dev/ttyUSB0', 9600, timeout=1)
ser.write(b'Hello, UART!\n')
resposta = ser.readline()
print(resposta.decode())
ser.close()