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.
Links simbólicos
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.







