Python & AI Tutorials Logo
Programação Python

29. Interagindo com o Sistema Operacional: sys e os

Programas Python não existem isoladamente — eles rodam em um sistema operacional que gerencia arquivos, diretórios, configurações de ambiente e como programas iniciam e se comunicam. Os módulos sys e os fornecem ferramentas para interagir com esse ambiente, permitindo que seus programas aceitem argumentos de linha de comando, leiam variáveis de ambiente, naveguem pelo sistema de arquivos e criem ou removam diretórios.

Entender esses módulos transforma seus scripts Python de código isolado em programas que podem se integrar ao sistema mais amplo, responder à entrada do usuário na inicialização e gerenciar arquivos e pastas de forma programática.

29.1) Argumentos de Linha de Comando e Usando sys.argv

Quando você executa um script Python a partir do terminal ou prompt de comando, você pode passar informações adicionais para ele — isso são os argumentos de linha de comando (command-line arguments). Por exemplo:

bash
python greet.py Alice 25

Aqui, greet.py é o nome do script, e Alice e 25 são argumentos passados para o programa. O módulo sys fornece acesso a esses argumentos por meio de sys.argv, uma lista contendo o nome do script e todos os argumentos como strings.

29.1.1) O que é sys.argv?

sys.argv é uma lista em que:

  • sys.argv[0] é sempre o nome do script que está sendo executado
  • sys.argv[1], sys.argv[2], etc., são os argumentos passados após o nome do script
  • Todos os elementos são strings, mesmo que pareçam números

Vamos criar um script simples para ver como isso funciona:

python
# show_args.py
import sys
 
print("Nome do script:", sys.argv[0])
print("Número de argumentos:", len(sys.argv))
print("Todos os argumentos:", sys.argv)

Se você executar esse script com:

bash
python show_args.py hello world 123

Output:

Script name: show_args.py
Number of arguments: 4
All arguments: ['show_args.py', 'hello', 'world', '123']

Repare que sys.argv contém 4 elementos: o nome do script mais três argumentos. O número 123 é armazenado como a string '123', não como um inteiro.

29.1.2) Usando Argumentos de Linha de Comando em Programas

Argumentos de linha de comando permitem que usuários personalizem o comportamento do programa sem modificar o código. Aqui está um programa de saudação que usa o primeiro argumento como nome:

python
# greet.py
import sys
 
if len(sys.argv) < 2:
    print("Uso: python greet.py <name>")
    sys.exit(1)  # Sair com código de erro
 
name = sys.argv[1]
print(f"Hello, {name}!")

Executando isso:

bash
python greet.py Alice

Output:

Hello, Alice!

Se você esquecer de fornecer um nome:

bash
python greet.py

Output:

Uso: python greet.py <name>

O programa verifica se foram fornecidos argumentos suficientes. Se não, ele imprime uma mensagem de uso e sai com sys.exit(1). O número 1 é um código de saída (exit code) — por convenção, 0 significa sucesso e valores diferentes de zero indicam erros. Isso ajuda outros programas ou scripts a detectar se seu programa executou com sucesso.

29.1.3) Convertendo Argumentos para Outros Tipos

Como todos os argumentos chegam como strings, muitas vezes você precisa convertê-los. Aqui está um programa que calcula a área de um retângulo:

python
# area.py
import sys
 
if len(sys.argv) < 3:
    print("Uso: python area.py <width> <height>")
    sys.exit(1)
 
try:
    width = float(sys.argv[1])
    height = float(sys.argv[2])
except ValueError:
    print("Error: Width and height must be numbers")
    sys.exit(1)
 
area = width * height
print(f"Area: {area}")

Executando isso:

bash
python area.py 5.5 3.2

Output:

Area: 17.6

Se o usuário fornecer uma entrada inválida:

bash
python area.py five three

Output:

Error: Width and height must be numbers

O bloco try-except (do Capítulo 25) lida com erros de conversão de forma elegante, fornecendo um feedback útil em vez de travar com um traceback.

Usuário executa: python script.py arg1 arg2

Python cria a lista sys.argv

sys.argv[0] = 'script.py'

sys.argv[1] = 'arg1'

sys.argv[2] = 'arg2'

Script acessa sys.argv

Processar argumentos como strings

Converter tipos se necessário

Usar valores na lógica do programa

29.2) Obtendo Informações do Interpretador e do Runtime com sys

O módulo sys fornece informações sobre o próprio interpretador Python e o ambiente de runtime. Isso é útil para debugging, logging, ou para escrever código que se adapta a diferentes versões do Python ou plataformas.

29.2.1) Informações de Versão do Python

sys.version e sys.version_info dizem qual versão do Python está executando seu código:

python
import sys
 
print("String da versão do Python:", sys.version)
print("Informações de versão:", sys.version_info)
print(f"Versão major: {sys.version_info.major}")
print(f"Versão minor: {sys.version_info.minor}")

Output (example):

Python version string: 3.11.4 (main, Jul  5 2023, 13:45:01) [GCC 11.2.0]
Version info: sys.version_info(major=3, minor=11, micro=4, releaselevel='final', serial=0)
Major version: 3
Minor version: 11

sys.version é uma string legível para humanos, enquanto sys.version_info é uma named tuple (tupla nomeada) que você pode comparar programaticamente:

python
import sys
 
if sys.version_info < (3, 8):
    print("Este programa requer Python 3.8 ou superior")
    sys.exit(1)
 
print("A versão do Python é compatível")

Isso garante que seu programa só rode em versões do Python compatíveis.

29.2.2) Informações de Plataforma

sys.platform identifica o sistema operacional:

python
import sys
 
print("Plataforma:", sys.platform)
 
if sys.platform == "win32":
    print("Executando no Windows")
elif sys.platform == "darwin":
    print("Executando no macOS")
elif sys.platform.startswith("linux"):
    print("Executando no Linux")
else:
    print("Executando em outra plataforma")

Output (on Linux):

Platform: linux
Running on Linux

Isso permite que você escreva código específico por plataforma quando necessário, como usar caminhos de arquivos ou comandos do sistema diferentes.

29.2.3) Caminho de Busca de Módulos

sys.path é uma lista de diretórios onde o Python procura quando você importa módulos:

python
import sys
 
print("Caminhos de busca de módulos:")
for path in sys.path:
    print(f"  {path}")

Output (example):

Module search paths:
  /home/user/projects
  /usr/lib/python3.11
  /usr/lib/python3.11/lib-dynload
  /home/user/.local/lib/python3.11/site-packages

A primeira entrada geralmente é o diretório que contém seu script. O Python pesquisa esses caminhos em ordem quando você usa import. Entender sys.path ajuda a depurar erros de importação ou adicionar diretórios personalizados de módulos.

29.2.4) Encerrando Programas com Códigos de Saída

Já vimos sys.exit() sendo usado para parar programas. Você pode passar um código de saída para indicar sucesso ou falha:

python
import sys
 
def process_data(filename):
    try:
        with open(filename) as f:
            data = f.read()
        # Processar dados...
        return True
    except FileNotFoundError:
        print(f"Error: File '{filename}' not found", file=sys.stderr)
        return False
 
if __name__ == "__main__":
    if len(sys.argv) < 2:
        print("Usage: python script.py <filename>", file=sys.stderr)
        sys.exit(1)
    
    success = process_data(sys.argv[1])
    sys.exit(0 if success else 1)

Códigos de saída seguem as convenções Unix:

  • 0 significa sucesso
  • Valores diferentes de zero indicam diferentes tipos de erro
  • Outros programas podem checar esses códigos para determinar se seu programa teve sucesso

29.3) Acessando Variáveis de Ambiente com os

Variáveis de ambiente (environment variables) são pares chave-valor definidos pelo sistema operacional ou pelo usuário, que programas podem ler. Elas são usadas para configuração, para armazenar caminhos, chaves de API e outras configurações que não deveriam ser hardcoded.

29.3.1) Lendo Variáveis de Ambiente

O módulo os fornece os.environ, um objeto do tipo dicionário contendo todas as variáveis de ambiente:

python
import os
 
# Obter uma variável de ambiente específica
home = os.environ.get('HOME')  # No Unix/Linux/macOS
print(f"Home directory: {home}")
 
# Retorna None se a variável não existir
api_key = os.environ.get('MY_API_KEY')
print(f"API key: {api_key}")

Output (on Linux):

Home directory: /home/alice
API key: None

Você pode fornecer um valor padrão:

python
import os
 
# Obter variável de ambiente com valor padrão
log_level = os.environ.get('LOG_LEVEL', 'INFO')
print(f"Log level: {log_level}")

Output (if LOG_LEVEL not set):

Log level: INFO

29.3.2) Variáveis de Ambiente Comuns

Sistemas operacionais diferentes fornecem variáveis de ambiente padrão:

python
import os
 
# Variáveis multiplataforma
print("Path:", os.environ.get('PATH'))
 
# Unix/Linux/macOS
print("User:", os.environ.get('USER'))
print("Home:", os.environ.get('HOME'))
print("Shell:", os.environ.get('SHELL'))
 
# Windows
print("User", os.environ.get('USERNAME'))
print("User Profile:", os.environ.get('USERPROFILE'))
print("Temp:", os.environ.get('TEMP'))

PATH é particularmente importante — ele lista diretórios onde o sistema procura programas executáveis. Quando você digita um comando como python, o sistema procura nesses diretórios.

29.3.3) Definindo Variáveis de Ambiente

Você pode modificar variáveis de ambiente para o seu programa e quaisquer subprocessos que ele criar:

python
import os
 
# Definir uma variável de ambiente
os.environ['MY_CONFIG'] = 'production'
 
# Ler de volta
print(os.environ.get('MY_CONFIG'))  # Output: production
 
# Excluir uma variável de ambiente
del os.environ['MY_CONFIG']

Importante: Alterações em os.environ afetam apenas o processo Python atual e quaisquer programas que ele iniciar. Elas não persistem depois que seu programa termina nem afetam outros programas.

29.4) Trabalhando com Caminhos de Arquivo e Diretórios (os.path, os.getcwd)

Gerenciar caminhos de arquivo corretamente é crucial para programas que trabalham com arquivos. Os módulos os e os.path fornecem ferramentas para construir, manipular e consultar caminhos de forma independente de plataforma.

29.4.1) Obtendo o Diretório de Trabalho Atual

O diretório de trabalho atual (current working directory, CWD) é a pasta que seu programa considera como ponto de partida para caminhos relativos:

python
import os
 
cwd = os.getcwd()
print(f"Current working directory: {cwd}")

Output (example):

Current working directory: /home/alice/projects/myapp

Quando você abre um arquivo com um caminho relativo como 'data.txt', o Python procura no diretório de trabalho atual. Entender o CWD ajuda a depurar erros de "arquivo não encontrado".

29.4.2) Alterando o Diretório Atual

Você pode alterar o diretório de trabalho com os.chdir():

python
import os
 
original = os.getcwd()
print("Original directory:", original)
 
# Mudar para um diretório diferente
os.chdir('/tmp')
print("New directory:", os.getcwd())
 
# Voltar
os.chdir(original)
print("Back to:", os.getcwd())

Output:

Original directory: /home/alice/projects
New directory: /tmp
Back to: /home/alice/projects

Nota: No Capítulo 28, você aprendeu sobre contextlib.chdir(), que restaura automaticamente o diretório original. Para mudanças simples de diretório, prefira usar o context manager:

python
from contextlib import chdir
 
with chdir('/tmp'):
    print("Temporarily in:", os.getcwd())
# Restaurado automaticamente

Isso garante que o diretório sempre seja restaurado, mesmo se ocorrer um erro.

29.4.3) Construindo Caminhos com os.path.join()

Sistemas operacionais diferentes usam separadores de caminho diferentes:

  • Unix/Linux/macOS: / (barra)
  • Windows: \ (barra invertida)

os.path.join() constrói caminhos corretamente para a plataforma atual:

python
import os
 
# Construir um caminho para um arquivo em um subdiretório
data_dir = 'data'
filename = 'users.txt'
filepath = os.path.join(data_dir, filename)
 
print(f"File path: {filepath}")

Output (on Unix/Linux/macOS):

File path: data/users.txt

Output (on Windows):

File path: data\users.txt

Você pode juntar múltiplos componentes:

python
import os
 
base = '/home/alice'
project = 'myapp'
subdir = 'data'
file = 'config.json'
 
full_path = os.path.join(base, project, subdir, file)
print(full_path)  # Output: /home/alice/myapp/data/config.json

Usar os.path.join() torna seu código portátil entre sistemas operacionais.

29.4.4) Verificando se Caminhos Existem

Antes de trabalhar com arquivos ou diretórios, verifique se eles existem:

python
import os
 
path = 'data.txt'
 
if os.path.exists(path):
    print(f"'{path}' exists")
else:
    print(f"'{path}' does not exist")

Você também pode verificar especificamente se é arquivo ou diretório:

python
import os
 
path = 'mydir'
 
if os.path.isfile(path):
    print(f"'{path}' is a file")
elif os.path.isdir(path):
    print(f"'{path}' is a directory")
elif os.path.exists(path):
    print(f"'{path}' exists but is neither a file nor directory")
else:
    print(f"'{path}' does not exist")

Essas verificações evitam erros ao tentar abrir arquivos inexistentes ou listar diretórios inexistentes.

29.4.5) Obtendo Caminhos Absolutos

os.path.abspath() converte caminhos relativos em caminhos absolutos:

python
import os
 
relative_path = 'data/users.txt'
absolute_path = os.path.abspath(relative_path)
 
print(f"Relative: {relative_path}")
print(f"Absolute: {absolute_path}")

Output (example):

Relative: data/users.txt
Absolute: /home/alice/projects/myapp/data/users.txt

Isso é útil para logs, mensagens de erro, ou quando você precisa saber o caminho exato de um arquivo.

29.4.6) Dividindo Caminhos em Componentes

os.path.split() separa um caminho em diretório e nome do arquivo:

python
import os
 
path = '/home/alice/projects/data.txt'
directory, filename = os.path.split(path)
 
print(f"Directory: {directory}")
print(f"Filename: {filename}")

Output:

Directory: /home/alice/projects
Filename: data.txt

os.path.basename() pega apenas o nome do arquivo, e os.path.dirname() pega apenas o diretório:

python
import os
 
path = '/home/alice/projects/data.txt'
 
print(f"Basename: {os.path.basename(path)}")  # Output: data.txt
print(f"Dirname: {os.path.dirname(path)}")    # Output: /home/alice/projects

29.4.7) Separando Extensões de Arquivo

os.path.splitext() separa o nome do arquivo de sua extensão:

python
import os
 
filename = 'report.pdf'
name, extension = os.path.splitext(filename)
 
print(f"Name: {name}")        # Output: report
print(f"Extension: {extension}")  # Output: .pdf

Isso é útil para processar arquivos com base no tipo:

python
import os
 
files = ['data.csv', 'image.png', 'document.txt', 'script.py']
 
for file in files:
    name, ext = os.path.splitext(file)
    if ext == '.csv':
        print(f"Process CSV file: {file}")
    elif ext == '.png':
        print(f"Process image file: {file}")

Output:

Process CSV file: data.csv
Process image file: image.png

29.5) Listando, Criando e Removendo Arquivos e Diretórios

O módulo os fornece funções para manipular o sistema de arquivos: listar conteúdo de diretórios, criar novos diretórios e remover arquivos e pastas.

29.5.1) Listando o Conteúdo de um Diretório

os.listdir() retorna uma lista de todos os itens em um diretório:

python
import os
 
# Listar conteúdo do diretório atual
contents = os.listdir('.')
print("Current directory contents:")
for item in contents:
    print(f"  {item}")

Output (example):

Current directory contents:
  script.py
  data.txt
  mydir
  README.md

A lista inclui tanto arquivos quanto diretórios. Para distinguir entre eles:

python
import os
 
contents = os.listdir('.')
print("Files:")
for item in contents:
    if os.path.isfile(item):
        print(f"  {item}")
 
print("\nDirectories:")
for item in contents:
    if os.path.isdir(item):
        print(f"  {item}")

Output:

Files:
  script.py
  data.txt
  README.md
 
Directories:
  mydir

29.5.2) Criando Diretórios

os.mkdir() cria um único diretório:

python
import os
 
new_dir = 'output'
 
if not os.path.exists(new_dir):
    os.mkdir(new_dir)
    print(f"Created directory: {new_dir}")
else:
    print(f"Directory already exists: {new_dir}")

Output:

Created directory: output

Importante: os.mkdir() falha se o diretório pai não existir. Por exemplo, tentar criar 'data/output' quando 'data' não existe vai gerar um erro.

os.makedirs() cria todos os diretórios pais necessários:

python
import os
 
nested_dir = 'data/processed/2024'
 
if not os.path.exists(nested_dir):
    os.makedirs(nested_dir)
    print(f"Created directory structure: {nested_dir}")

Output:

Created directory structure: data/processed/2024

Isso cria data, depois data/processed, depois data/processed/2024 se eles não existirem.

29.5.3) Removendo Arquivos

os.remove() exclui um arquivo:

python
import os
 
filename = 'temp.txt'
 
# Criar um arquivo temporário
with open(filename, 'w') as f:
    f.write('Temporary data')
 
print(f"File exists: {os.path.exists(filename)}")  # Output: True
 
# Remover o arquivo
os.remove(filename)
print(f"File exists: {os.path.exists(filename)}")  # Output: False

Aviso: os.remove() exclui arquivos permanentemente — eles não vão para a lixeira.

29.5.4) Removendo Diretórios

os.rmdir() remove um diretório vazio:

python
import os
 
directory = 'empty_dir'
 
# Criar e depois remover um diretório vazio
os.mkdir(directory)
print(f"Created: {directory}")
 
os.rmdir(directory)
print(f"Removed: {directory}")

os.rmdir() falha se o diretório contiver arquivos. Para remover um diretório e todo o seu conteúdo, você precisa excluir os arquivos primeiro:

python
import os
 
def remove_directory_contents(directory):
    """Remove todos os arquivos em um diretório e então remove o diretório.
    
    Nota: Falha se o diretório contiver subdiretórios.
    """
    if not os.path.exists(directory):
        print(f"Directory does not exist: {directory}")
        return
    
    # Remover todos os arquivos no diretório
    for item in os.listdir(directory):
        item_path = os.path.join(directory, item)
        if os.path.isfile(item_path):
            os.remove(item_path)
            print(f"Removed file: {item_path}")
    
    # Remover o diretório agora vazio
    os.rmdir(directory)
    print(f"Removed directory: {directory}")
 
# Exemplo de uso
test_dir = 'test_data'
os.makedirs(test_dir, exist_ok=True)
 
# Criar alguns arquivos de teste
with open(os.path.join(test_dir, 'file1.txt'), 'w') as f:
    f.write('test')
with open(os.path.join(test_dir, 'file2.txt'), 'w') as f:
    f.write('test')
 
# Remover tudo
remove_directory_contents(test_dir)

Output:

Removed file: test_data/file1.txt
Removed file: test_data/file2.txt
Removed directory: test_data

Nota: Para remoção de diretórios mais complexa (incluindo subdiretórios), o módulo shutil do Python fornece shutil.rmtree(), mas isso está além do nosso escopo atual.

29.5.5) Renomeando Arquivos e Diretórios

os.rename() renomeia ou move arquivos e diretórios:

python
import os
 
# Renomear um arquivo
old_name = 'draft.txt'
new_name = 'final.txt'
 
# Criar arquivo de teste
with open(old_name, 'w') as f:
    f.write('content')
 
os.rename(old_name, new_name)
print(f"Renamed '{old_name}' to '{new_name}'")

Você também pode mover arquivos para diretórios diferentes:

python
import os
 
# Criar diretórios e arquivo
os.makedirs('source', exist_ok=True)
os.makedirs('destination', exist_ok=True)
 
with open('source/file.txt', 'w') as f:
    f.write('content')
 
# Mover arquivo para um diretório diferente
os.rename('source/file.txt', 'destination/file.txt')
print("Moved file to destination directory")

Os módulos sys e os dão aos seus programas Python a capacidade de interagir com o sistema operacional, aceitar entrada pela linha de comando, ler configuração e gerenciar arquivos e diretórios. Essas capacidades transformam scripts simples em ferramentas poderosas de linha de comando que se integram perfeitamente ao ambiente mais amplo do sistema.


© 2025. Primesoft Co., Ltd.
support@primesoft.ai