Linux / Comando mktemp: criar arquivos e diretórios temporários

O comando GNU mktemp cria um arquivo ou diretório temporário com nome difícil de prever e informa o caminho criado. Ele escolhe o nome e cria o objeto em uma única operação, reduzindo a disputa por nomes previsíveis em scripts. Verifique o sucesso da criação, use o caminho entre aspas e planeje a limpeza: o comando não remove o objeto automaticamente.

Os exemplos usam Bash e GNU Coreutils. Confira mktemp --version, mktemp --help e man mktemp no sistema de destino. Prepare uma pasta em que você possa escrever, sob seu controle, sem alterações simultâneas de outros processos. A primeira prática cria uma área própria dentro da pasta atual; os scripts de limpeza devem ser salvos e executados como arquivos, sem colá-los no terminal interativo nem carregá-los com source.

O que é o comando mktemp?

Uma condição de corrida ocorre quando outro processo pode alterar um nome entre a escolha e o uso. Acrescentar apenas o identificador do processo, como $$, não impede que alguém antecipe esse nome. mktemp cria o objeto de forma atômica, isto é, sem separar a escolha e a criação em duas etapas expostas. Isso não transforma uma pasta controlada por terceiros em um local confiável. O manual GNU de mktemp descreve os modelos, as permissões iniciais e a seleção do diretório.

Sintaxe básica

mktemp [opções]... [modelo]

opções e modelo são marcadores. No GNU, o último componente do modelo precisa conter uma sequência de pelo menos três X; é a última sequência que será substituída. Use aspas em caminhos com espaços e -- antes do modelo quando necessário. Opções e detalhes variam entre implementações; não presuma que toda extensão GNU funciona em outros sistemas.

Uso básico do mktemp

Criar um arquivo temporário

Execute a cadeia completa abaixo no mesmo terminal e pare se houver erro. mktemp_demo recebe uma pasta exclusiva criada dentro da pasta atual. Na chamada sem argumentos, mktemp usa o modelo padrão tmp.XXXXXXXXXX e considera TMPDIR, ou /tmp no GNU quando essa variável não define um local. A atribuição antes do comando limita TMPDIR àquela chamada e mantém o arquivo dentro da área de prática.

mktemp_start=$PWD
mktemp_demo=$(mktemp -d -p "$PWD" 'mktemp-demo.XXXXXXXX') &&
cd -- "$mktemp_demo" &&
tmp_file=$(TMPDIR="$mktemp_demo" mktemp) &&
printf '%s\n' "$tmp_file"

Escolher um padrão de nome

Estas chamadas usam modelos explícitos e, sem -p ou --tmpdir, criam os arquivos na pasta atual. O GNU aceita o sufixo .csv depois da última sequência de X ou um sufixo separado com --suffix. Com essa opção explícita, o modelo precisa terminar em X e o sufixo não pode conter /. Os nomes exibidos variam a cada criação; não copie um nome de exemplo como se fosse fixo.

mktemp report-XXXXXXXX.csv
mktemp --suffix=.log app-XXXXXXXX

Criar um diretório temporário

-d cria uma pasta em vez de um arquivo. No Linux com as permissões usuais, o GNU solicita leitura e escrita apenas para o dono nos arquivos, normalmente 0600, e leitura, escrita e travessia apenas para o dono nas pastas, normalmente 0700. umask, a máscara de criação de permissões, pode restringir ainda mais esses modos; políticas e mapeamentos do sistema de arquivos também precisam ser considerados.

tmp_dir=$(TMPDIR="$mktemp_demo" mktemp -d) &&
printf '%s\n' "$tmp_dir"

Conferir o caminho realmente criado

Atribua a saída a uma variável e só a use depois de uma criação bem-sucedida. A consulta abaixo cria outro arquivo dentro da área preparada, imprime o caminho e confirma que ele é um arquivo regular sem ser um link simbólico. Isso confere o estado observado naquele momento; não reserva um nome para uma criação futura nem elimina alterações concorrentes posteriores.

tmpfile=$(mktemp -p "$mktemp_demo" 'check-XXXXXXXX') &&
printf '%s\n' "$tmpfile" &&
test -f "$tmpfile" && test ! -L "$tmpfile" &&
printf '%s\n' 'Arquivo temporário confirmado.'

A saída esperada é um caminho e depois Arquivo temporário confirmado.. Se a criação ou a consulta falhar, a mensagem de confirmação não será impressa e a cadeia terá uma saída diferente de zero. O comando não agenda exclusão: os arquivos destas práticas continuam disponíveis. Para remover um arquivo conhecido, confira primeiro a variável e use rm -- "$tmpfile"; para uma pasta vazia conhecida, use rmdir -- "$tmp_dir".

Principais opções

Opção Comportamento GNU
-d, --directory Criar uma pasta em vez de um arquivo.
-p PASTA, --tmpdir=PASTA Interpretar um modelo relativo à pasta indicada. O modelo não pode ser absoluto; pastas intermediárias precisam existir.
--tmpdir Sem valor, usar TMPDIR se definido, senão /tmp. Para um valor, use --tmpdir=PASTA; -p exige argumento.
--suffix=SUFIXO Acrescentar um sufixo sem /. O modelo fornecido precisa terminar em X.
-q, --quiet Ocultar o diagnóstico de falha, mantendo o estado de saída diferente de zero.
-u, --dry-run Gerar um nome não existente no momento, sem criar o objeto. Não usar o nome para criar depois um arquivo que exija segurança.

Um modelo explícito sem seleção de pasta pode usar a pasta atual mesmo quando TMPDIR estiver definido. -p PASTA seleciona explicitamente a pasta; --tmpdir sem valor consulta o ambiente. Evite a opção obsoleta -t em novos scripts. A saída zero indica sucesso; no uso normal, falhas de criação retornam 1. Com -q, continue verificando esse estado, pois a ausência de mensagem não significa sucesso.

Exemplos práticos

Limpar um arquivo com trap

Salve o exemplo completo como temp-file.sh e execute bash temp-file.sh "$mktemp_demo". O argumento deve ser uma pasta existente sob seu controle. O script cria um arquivo nela, registra a limpeza em EXIT, escreve e mostra dados temporários. Ao sair, remove somente o nome criado. Uma falha de limpeza transforma sucesso em erro, sem esconder um erro que já existia.

#!/usr/bin/env bash
if (( $# != 1 )) || [[ -z $1 || ! -d $1 ]]; then
  printf '%s\n' 'Uso: bash temp-file.sh PASTA_EXISTENTE' >&2
  exit 2
fi
tmp_file=$(mktemp -p "$1" 'file-XXXXXXXX') || exit 1
readonly tmp_file
cleanup() {
  status=$?
  trap - EXIT HUP INT TERM
  if ! rm -f -- "$tmp_file"; then
    printf '%s\n' 'Falha ao remover o temporário.' >&2
    if (( status == 0 )); then status=1; fi
  fi
  exit "$status"
}
trap cleanup EXIT
trap 'exit 129' HUP
trap 'exit 130' INT
trap 'exit 143' TERM
printf 'Criado: %s\n' "$tmp_file"
printf '%s\n' 'dados temporários' > "$tmp_file" || exit 1
cat -- "$tmp_file" || exit 1

Processar arquivos em um diretório temporário

Salve como temp-work.sh e execute bash temp-work.sh "$mktemp_demo". São necessários Bash, GNU mktemp, rm, rmdir, tr e cat. O script escreve temporary data em input, converte o texto e mostra TEMPORARY DATA. A limpeza remove somente input e output, depois tenta remover a pasta vazia: arquivos inesperados impedem essa última etapa e são preservados para inspeção.

#!/usr/bin/env bash
if (( $# != 1 )) || [[ -z $1 || ! -d $1 ]]; then
  printf '%s\n' 'Uso: bash temp-work.sh PASTA_EXISTENTE' >&2
  exit 2
fi
work_dir=$(mktemp -d -p "$1" 'work-XXXXXXXX') || exit 1
readonly work_dir
cleanup() {
  status=$?
  trap - EXIT HUP INT TERM
  cleanup_error=0
  if [[ -d $work_dir && ! -L $work_dir ]]; then
    rm -f -- "$work_dir/input" "$work_dir/output" || cleanup_error=1
    rmdir -- "$work_dir" || cleanup_error=1
  else
    printf '%s\n' 'Pasta temporária inesperada; limpeza recusada.' >&2
    cleanup_error=1
  fi
  if (( status == 0 && cleanup_error != 0 )); then status=1; fi
  exit "$status"
}
trap cleanup EXIT
trap 'exit 129' HUP
trap 'exit 130' INT
trap 'exit 143' TERM
readonly input="$work_dir/input" output="$work_dir/output"
printf 'Criado: %s\n' "$work_dir"
printf '%s\n' 'temporary data' > "$input" || exit 1
tr '[:lower:]' '[:upper:]' < "$input" > "$output" || exit 1
cat -- "$output" || exit 1

Nos dois scripts, HUP, INT e TERM solicitam saída com os estados convencionais 129, 130 e 143, passando pela limpeza de EXIT. Colocar apenas uma remoção no tratador de sinal pode permitir que o script continue usando um caminho já removido. SIGKILL e SIGSTOP não podem ser tratados; queda de energia também pode deixar resíduos. O Bash pode adiar um tratador enquanto espera um comando em primeiro plano, conforme o manual de sinais do Bash. A definição de trap e EXIT explica quando as ações são executadas.

Selecionar a pasta pai

A pasta pai precisa existir e permitir a criação. O exemplo prepara uma pasta de cache dentro da área de prática e usa -p explicitamente. Criar o temporário no mesmo sistema de arquivos do destino pode ser necessário para uma renomeação atômica posterior, mas mktemp sozinho não publica o arquivo, não valida seu conteúdo e não torna uma operação entre sistemas de arquivos atômica.

mkdir -p -- "$mktemp_demo/cache" &&
cache_file=$(mktemp -p "$mktemp_demo/cache" 'cache-XXXXXXXX') &&
printf '%s\n' "$cache_file"

Comparar mktemp, touch e mkdir

Comando ou método Função principal Quando usar
mktemp Criar nome e objeto em uma operação Temporários com criação verificada em uma pasta adequada
touch Atualizar horários e criar arquivo ausente Nome fixo conhecido; não substitui a criação segura de temporários
mkdir Criar a pasta com o nome fornecido Estruturas previamente definidas; recusa um nome já existente sem -p
mktemp -u Escolher apenas um nome no momento Não usar para criar depois um temporário seguro

O comando touch também pode apenas alterar horários de um arquivo existente; ele não garante um arquivo novo com nome imprevisível. Use mkdir para uma estrutura com nomes definidos e rmdir para remover uma pasta que deve estar vazia.

Cuidados importantes

Não crie um arquivo posteriormente a partir da saída de mktemp -u

Entre gerar um nome com -u e abri-lo, outro processo pode ocupar o caminho. O fato de o nome ser difícil de prever não elimina essa janela. Deixe mktemp criar o objeto diretamente e interrompa a operação se a criação falhar.

Coloque entre aspas as variáveis de limpeza

Aspas impedem a separação indevida de caminhos com espaços e a expansão de padrões, mas não tornam correto um caminho errado. Guarde o caminho retornado, não o substitua por um palpite e mantenha as variáveis de limpeza intactas. Nos scripts, readonly impede a reatribuição da variável; não impede que outro processo altere o sistema de arquivos. Não amplie uma limpeza limitada para rm -rf sem definir e conferir todo o escopo.

Saiba onde os dados temporários sensíveis são armazenados

Uma pasta temporária pode estar em disco, em memória, em swap ou incluída em snapshots e backups. Remover o nome não elimina automaticamente todas essas cópias. Verifique a política do sistema antes de gravar segredos. Ao terminar a prática, volte com cd -- "$mktemp_start"; a pasta de demonstração e os objetos criados fora dos scripts permanecem para inspeção e remoção individual.

Perguntas frequentes

Por que mktemp é mais seguro do que adicionar um ID de processo a um nome?

Porque ele escolhe um nome difícil de prever e cria o objeto na mesma operação, reduzindo a oportunidade de outro processo ocupar antecipadamente aquele nome. Ainda é necessário usar uma pasta adequada, conferir a criação e proteger o uso posterior do caminho.

Como criar um diretório temporário?

Use mktemp -d, verifique o estado de saída e guarde o caminho retornado. Use a variável entre aspas. No GNU, um modelo omitido considera TMPDIR ou /tmp; -p permite escolher outra pasta existente.

Os arquivos temporários são removidos automaticamente?

O próprio mktemp não agenda a remoção. Um script pode usar trap para limpar objetos conhecidos ao sair, mas sinais não tratáveis e interrupções do sistema podem deixar resíduos. A limpeza periódica do sistema, quando existir, segue outra política e não substitui o controle do script.

Quando o TMPDIR é usado?

No GNU, a chamada sem modelo implica --tmpdir e considera TMPDIR, com /tmp como alternativa. Um modelo explícito sem seleção de pasta normalmente usa a pasta atual. Use -p PASTA ou --tmpdir=PASTA para escolher explicitamente e confira o caminho retornado.