posix no Python: chamadas Unix diretas

Publicado em: 26/08/2026
Tempo de leitura: 7 minutos
Macro shot capturing detailed patterns of a python in its natural surroundings.

O módulo posix expõe chamadas de sistema comuns em plataformas compatíveis com POSIX. Ele fornece uma interface de baixo nível para arquivos, diretórios, processos, descritores, permissões, usuários, grupos e informações do sistema. Na prática, quase todo código de aplicação deve importar os, porque esse módulo oferece uma camada mais portátil e inclui a maior parte da API de posix.

Conhecer posix, porém, ajuda a entender como o Python conversa com sistemas Unix, como Linux, macOS e BSD. Também é útil ao investigar comportamento específico da plataforma, escrever ferramentas administrativas, analisar diferenças entre builds do interpretador e compreender a origem de funções disponíveis em os.

Disponibilidade e portabilidade

posix só existe quando o Python foi compilado para um sistema que fornece a interface correspondente. Em Windows, o módulo normalmente não está disponível. Por isso, uma biblioteca distribuída para vários sistemas não deve importar posix diretamente no nível global sem tratamento.

try:
    import posix
except ImportError:
    posix = None

if posix is None:
    print("Interface POSIX indisponível")

Mesmo em Unix, funções individuais podem variar conforme o kernel, a biblioteca C, as opções de compilação e a versão do Python. Verifique recursos com hasattr() ou, preferencialmente, use as coleções de capacidades fornecidas por os.

Por que preferir os

O módulo os seleciona internamente a implementação adequada ao sistema operacional. Em Unix, muitas funções de os são fornecidas por posix; em Windows, a implementação correspondente é diferente. Assim, os.open(), os.stat() e os.getpid() mantêm uma interface consistente.

import os

print(os.getpid())
print(os.getcwd())

Importe posix diretamente somente quando o objetivo for explicitamente estudar, testar ou depender de comportamento POSIX. Em código comum, a escolha mais segura e legível é os.

Trabalhando com descritores de arquivo

Funções de baixo nível operam com descritores inteiros. open() abre um caminho e retorna um descritor; read() e write() trabalham com bytes; close() libera o recurso.

import os

fd = os.open("dados.bin", os.O_RDONLY)
try:
    bloco = os.read(fd, 4096)
    print(len(bloco))
finally:
    os.close(fd)

O bloco finally é obrigatório em padrões manuais. Para arquivos comuns, open() da linguagem e um bloco with são mais convenientes porque gerenciam fechamento, buffering, texto e encoding.

Flags de abertura

Chamadas POSIX combinam flags como O_RDONLY, O_WRONLY, O_RDWR, O_CREAT, O_EXCL, O_APPEND e, quando disponível, O_CLOEXEC. O operador bit a bit | monta a configuração.

import os

flags = os.O_WRONLY | os.O_CREAT | os.O_EXCL
fd = os.open("novo.txt", flags, 0o600)
try:
    os.write(fd, b"conteudo privado\n")
finally:
    os.close(fd)

O_EXCL com O_CREAT evita sobrescrever um arquivo existente e reduz condições de corrida. O modo 0o600 solicita leitura e escrita apenas ao proprietário, mas a umask do processo também participa da permissão final.

Caminhos como str ou bytes

Em Unix, caminhos podem ser fornecidos como str ou bytes. Use str na maioria dos programas. Bytes são úteis quando é necessário preservar nomes que não podem ser decodificados pelo encoding do sistema de arquivos.

Não misture os dois tipos na mesma operação. Funções que recebem caminho em bytes normalmente retornam nomes em bytes. os.fsencode() e os.fsdecode() convertem usando a política do Python para o sistema de arquivos.

Informações de arquivos com stat

stat() retorna tamanho, timestamps, proprietário, grupo, modo e outros campos. Use o módulo stat para interpretar os bits de modo.

import os
import stat

info = os.stat("dados.bin", follow_symlinks=False)
print(info.st_size)
print(stat.filemode(info.st_mode))
print(stat.S_ISREG(info.st_mode))

Quando a segurança depende do objeto analisado, evite a sequência “verificar e depois abrir”, pois outro processo pode trocar o caminho entre as duas operações. Prefira APIs baseadas em descritor ou parâmetros dir_fd e follow_symlinks quando disponíveis.

stat() normalmente segue links simbólicos, enquanto lstat() descreve o próprio link. A distinção é importante em scanners, backups, instaladores e ferramentas de limpeza.

import os

alvo = os.readlink("atalho")
info_link = os.lstat("atalho")
print(alvo, info_link.st_mode)

Nunca presuma que um caminho confiável continua apontando para o mesmo objeto. Em diretórios compartilhados, ataques de troca de symlink podem redirecionar operações privilegiadas.

Permissões e umask

chmod() altera bits de permissão. umask() define quais permissões serão removidas na criação de novos objetos. Como a umask é estado global do processo, alterá-la em uma aplicação com várias threads é arriscado.

import os

os.chmod("novo.txt", 0o600)

Não use chmod(0o777) como solução genérica. Defina o mínimo necessário e considere ACLs, políticas do container, volumes montados e identidade efetiva.

Usuário, grupo e processo

Funções como getpid(), getppid(), getuid(), geteuid(), getgid() e getegid() descrevem o processo. Identidade real e efetiva podem divergir em programas com privilégios especiais.

import os

print({
    "pid": os.getpid(),
    "uid": os.getuid(),
    "euid": os.geteuid(),
    "gid": os.getgid(),
})

Para converter UID e GID em nomes, consulte os artigos sobre pwd no Python e grp no Python. Não use essas bases como mecanismo de autenticação.

Variáveis de ambiente

No nível POSIX, o ambiente é uma coleção de chaves e valores associada ao processo. Em Python, prefira os.environ, que oferece um mapeamento mutável e mantém as alterações sincronizadas para subprocessos futuros.

import os

modo = os.environ.get("APP_MODE", "development")
os.environ["APP_CHILD_FLAG"] = "1"

Não registre todo o ambiente, pois ele pode conter tokens, senhas e caminhos privados. Valide valores antes de usá-los em comandos ou nomes de arquivo.

Criação de processos

POSIX fornece primitivas como fork(), execve(), waitpid() e _exit(). Elas são poderosas, mas exigem cuidado com threads, buffers, locks e descritores herdados.

Para executar programas, prefira subprocess. A API resolve redirecionamento, argumentos, códigos de saída, timeouts e fechamento de descritores de maneira mais segura.

import subprocess

resultado = subprocess.run(
    ["uname", "-s"],
    check=True,
    capture_output=True,
    text=True,
    timeout=5,
)
print(resultado.stdout.strip())

Evite shell=True com entrada não confiável. Passe argumentos como lista.

Fork em processos com threads

Depois de fork(), somente a thread que chamou a função continua no filho. Locks mantidos por outras threads podem ficar permanentemente bloqueados. Bibliotecas de banco de dados, logging, TLS e alocadores também podem possuir estado inconsistente.

Em aplicações modernas, use subprocess ou métodos de inicialização adequados de multiprocessing. Não execute lógica Python complexa entre fork() e exec() em programas multithread.

Descritores herdados

Um descritor aberto pode vazar para um processo filho e manter arquivos, sockets ou pipes ativos. Python cria muitos descritores como não herdáveis por padrão, mas código nativo e configurações explícitas podem mudar isso.

Use os.get_inheritable(), os.set_inheritable() e opções de subprocess conscientemente. O artigo de fcntl no Python mostra flags e locks em Unix.

Operações relativas a diretórios

Várias funções aceitam dir_fd. Em vez de concatenar caminhos, o programa abre um diretório confiável e resolve nomes relativos a ele. Isso pode reduzir corridas e tornar operações de sandbox mais controláveis.

import os

base_fd = os.open("dados", os.O_RDONLY | os.O_DIRECTORY)
try:
    fd = os.open("item.txt", os.O_RDONLY, dir_fd=base_fd)
    try:
        print(os.read(fd, 100))
    finally:
        os.close(fd)
finally:
    os.close(base_fd)

Nem toda função ou plataforma aceita dir_fd. Consulte os.supports_dir_fd.

Sincronização e durabilidade

fsync() solicita a gravação dos dados e metadados associados ao descritor. Em atualizações críticas, grave em arquivo temporário no mesmo sistema de arquivos, sincronize, renomeie atomicamente e, quando necessário, sincronize o diretório.

Uma chamada bem-sucedida não garante proteção contra todas as falhas de hardware ou configurações de cache. Durabilidade depende do sistema de arquivos, dispositivo, montagem e infraestrutura.

Erros e OSError

Falhas de chamadas do sistema aparecem como subclasses de OSError, como FileNotFoundError, PermissionError, FileExistsError e IsADirectoryError.

from pathlib import Path

try:
    dados = Path("config.ini").read_text(encoding="utf-8")
except FileNotFoundError:
    dados = ""
except PermissionError as erro:
    raise RuntimeError("sem permissão para ler config.ini") from erro

Capture a exceção mais específica que permita uma ação real. Não esconda erros inesperados com except OSError: pass.

Limites de recursos

Chamadas POSIX podem falhar por falta de descritores, memória, espaço em disco ou limites de processo. O artigo sobre resource no Python explica como observar e definir alguns limites em Unix.

Trate erros, imponha timeouts e limite o volume de entrada. Uma ferramenta que percorre diretórios ou abre muitos arquivos deve fechar recursos progressivamente.

Teste em sistemas reais

Containers não reproduzem todas as diferenças de macOS, Linux e BSD. Teste permissões, symlinks, nomes em bytes, mounts somente leitura, NFS, falta de espaço, UIDs diferentes, umask, sinais e descritores herdados.

Também teste com privilégios reduzidos. Executar apenas como administrador pode esconder falhas de permissão e criar uma falsa sensação de segurança.

Erros comuns

Os erros mais frequentes são importar posix quando os resolveria, presumir que todas as funções existem, esquecer de fechar descritores, misturar caminhos em texto e bytes, seguir symlinks sem intenção, alterar umask global em várias threads, usar fork() de forma insegura e capturar OSError sem diagnóstico.

Conclusão

posix revela a camada de chamadas de sistema usada pelo Python em Unix, mas os deve continuar sendo a interface padrão para a maioria dos projetos. Use APIs de alto nível quando elas expressarem melhor a intenção e recorra a descritores, flags e operações relativas a diretórios quando precisar de controle real.

Valide capacidades, feche recursos, reduza privilégios e trate caminhos compartilhados como mutáveis. Consulte a documentação oficial de posix e a documentação de os.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Conteúdo do artigo

    Artigos relacionados

    A male software engineer working on code in a modern office setting.
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    curses no Python: interfaces no terminal

    Aprenda curses no Python para criar interfaces de terminal com janelas, cores, teclado, resize, Unicode e cleanup seguro.

    Ler mais

    Tempo de leitura: 7 minutos
    26/08/2026
    Detailed close-up of a reticulated python showcasing intricate scales and piercing eyes.
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    grp no Python: consulte grupos Unix

    Aprenda grp no Python para consultar grupos Unix, GIDs, membros, ownership e grupos suplementares com NSS e containers.

    Ler mais

    Tempo de leitura: 6 minutos
    26/08/2026
    A person typing on a laptop with a Python programming book visible, capturing technology and learning.
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    pwd no Python: consulte usuários Unix

    Aprenda pwd no Python para consultar usuários Unix por UID ou login, obter home, shell e ownership sem usar a

    Ler mais

    Tempo de leitura: 6 minutos
    26/08/2026
    Close-up view of freshly cut log slices stacked for wood storage, showing natural texture.
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    syslog no Python: envie logs ao sistema

    Aprenda syslog no Python para enviar logs Unix com prioridades, facilities, máscaras, conteúdo estruturado e proteção contra log injection.

    Ler mais

    Tempo de leitura: 6 minutos
    26/08/2026
    A CPU and RAM sticks displayed on a white surface, showcasing computer hardware components.
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    resource no Python: limites de CPU e memória

    Aprenda resource no Python para medir CPU, memória e page faults, definir limites de arquivos, processos e descriptors em Unix.

    Ler mais

    Tempo de leitura: 7 minutos
    26/08/2026
    Close-up of a parking payment terminal in an indoor garage in Almere, Netherlands.
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    pty no Python: automatize terminais Unix

    Aprenda pty no Python para executar e testar programas interativos, controlar pseudo-terminais, tratar EOF, resize, sinais e timeouts.

    Ler mais

    Tempo de leitura: 6 minutos
    25/08/2026