Os arquivos temporários devem ser salvos em / tmp ou no diretório de trabalho atual?

76

Eu tenho um programa que precisa gerar arquivos temporários. Está escrito para máquinas de cluster.

Se eu salvei esses arquivos em um diretório temporário em todo o sistema (por exemplo /tmp:), alguns usuários reclamaram que o programa falhou porque não tinham acesso adequado ao / tmp. Mas se eu salvei esses arquivos no diretório de trabalho, esses usuários também reclamaram que não queriam ver esses arquivos misteriosos.

Qual é a melhor prática? Devo insistir que salvar para /tmpé a abordagem correta e defender qualquer falha como "funcionando como pretendido" (por exemplo, solicite ao administrador permissão / acesso adequados)?

SmallChess
fonte
3
verifique se o programa tem acesso e se não encontrar outro dir temporário
catraca aberração
24
Se o seu administrador estragou os direitos de acesso, ele definitivamente deve corrigi-lo. O que você faria se o seu administrador esquecesse de adicionar direitos de execução ao seu programa?
Doc Brown
7
Você não encontrará / tmp na maioria dos sistemas Windows, mas há uma chamada do SO que informa onde colocar os arquivos temporários.
Ian
28
Se algumas pessoas não tiveram acesso a /tmpum sistema semelhante ao Unix, isso foi configurado incorretamente. O superusuário deve fazer algo parecido chmod 1777 /tmp.
Musiphil
12
Cuidado para que $ TMPDIR possa apontar para um caminho diferente daquele /tmp/que você deve usar. Veja algumas das respostas;)
marcelm 6/16/16

Respostas:

141

Os arquivos temporários precisam ser armazenados no diretório temporário do sistema operacional por vários motivos:

  • O sistema operacional facilita a criação desses arquivos, garantindo que seus nomes sejam exclusivos .

  • A maioria dos softwares de backup sabe quais são os diretórios que contêm arquivos temporários e os ignora. Se você usar o diretório atual, poderá ter um efeito importante no tamanho dos backups incrementais, se os backups forem feitos com freqüência.

  • O diretório temporário pode estar em um disco diferente ou na RAM, tornando o acesso de leitura e gravação muito, muito mais rápido .

  • Os arquivos temporários são freqüentemente excluídos durante a reinicialização (se estiverem em um ramdisk, eles serão simplesmente perdidos). Isso reduz o risco de crescimento infinito se o seu aplicativo nem sempre remover os arquivos temporários corretamente (por exemplo, após uma falha).

    A limpeza de arquivos temporários do diretório de trabalho pode facilmente tornar-se uma bagunça se os arquivos forem armazenados juntamente com os arquivos do aplicativo e do usuário. Você pode atenuar esse problema criando um diretório separado no diretório atual, mas isso pode levar a outro problema:

  • O comprimento do caminho pode ser muito longo em algumas plataformas. Por exemplo, no Windows, os limites de caminho para algumas APIs, estruturas e aplicativos são terríveis , o que significa que você pode atingir facilmente esse limite se o diretório atual já estiver dentro da hierarquia da árvore e os nomes de seus arquivos temporários forem muito longos.

  • Nos servidores, o monitoramento do crescimento do diretório temporário geralmente é feito imediatamente. Se você usar um diretório diferente, ele poderá não ser monitorado, e o monitoramento de todo o disco não ajudará a descobrir facilmente que são os arquivos temporários que ocupam cada vez mais espaço.

Quanto aos erros de acesso negado, deixe o sistema operacional criar um arquivo temporário para você. O sistema operacional pode, por exemplo, saber que, para um determinado usuário, um diretório diferente /tmpou C:\Windows\tempdeve ser usado; portanto, acessando esses diretórios diretamente, você pode realmente encontrar um erro de acesso negado.

Se você receber um acesso negado, mesmo ao usar a chamada do sistema operacional, isso significa simplesmente que a máquina estava mal configurada; isso foi explicado pela Blrfl . Cabe ao administrador do sistema configurar a máquina; você não precisa alterar seu aplicativo.

A criação de arquivos temporários é direta em muitos idiomas. Alguns exemplos:

  • Bater:

    # The next line will create a temporary file and return its path.
    path="$(mktemp)"
    echo "Hello, World!" > "$path"
  • Pitão:

    import tempfile
    
    # Creates a file and returns a tuple containing both the handle and the path.
    handle, path = tempfile.mkstemp()
    with open(handle, "w") as f:
        f.write("Hello, World!");
  • C #:

    // Creates a file and returns the path.
    var path = Path.GetTempFileName();
    File.WriteAllText(path, "Hello, World!");
  • PHP:

    # Creates a file and returns the handle.
    $temp = tmpfile();
    fwrite($temp, "Hello, World!");
    fclose($temp);
  • Rubi:

    require "tempfile"
    
    # Creates a file and returns the file object.
    file = Tempfile.new ""
    file << "Hello, World!"
    file.close

Observe que em alguns casos, como no PHP e Ruby, o arquivo é removido quando o identificador é fechado. Esse é um benefício adicional de usar as bibliotecas incluídas na linguagem / estrutura.

Arseni Mourzenko
fonte
2
O que você quer dizer com "certifique-se de deixar o sistema operacional criar um arquivo temporário para você". Então, em vez de, por exemplo, fopen("/tmp/mytmpfile", "w");eu deveria fazer alguma chamada do sistema para lidar com arquivos temporários?
simon
30
@ gurka: Você deve estar ligando tmpfile(3)para gerar seus arquivos temporários, ou pelo menos ligando mktemp(3)para criar os nomes dos arquivos.
TMN
3
@TMN: São apenas funções de biblioteca que são executadas no espaço do usuário e não têm mágica para contornar o erro de permissão fornecido pelo sistema operacional.
Musiphil
25
@musiphil O tmpfile e o mktemp usam variáveis ​​externas para determinar o caminho para arquivos temporários. Eles podem ter sido configurados para apontar para outro diretório que não seja / tmp /, talvez um diretório por usuário. Tentar criar um nome de arquivo manualmente em / tmp / pode falhar, enquanto tmpfile e mktemp retornam caminhos válidos.
pipe
2
@musiphil: Eu nunca disse que eles resolveriam o problema de permissão, estava respondendo à sua pergunta sobre o uso de chamadas do sistema para criar os arquivos.
TMN
33

Devo insistir que salvar em / tmp é a abordagem correta e me defender de qualquer falha como "funcionando como pretendido" (por exemplo, solicite ao administrador acesso de permissão adequado)?

Existem padrões para isso, e a melhor coisa que você pode fazer é obedecer a eles.

O POSIX, que é seguido por praticamente todos os SOs não mainframe de qualquer significado que você possa encontrar, possui disposições para a criação de arquivos temporários nomeados exclusivamente em um diretório usando valores padrão que podem ser reconfigurados pelo ambiente:

  • O stdio.hcabeçalho C pode opcionalmente incluir uma P_tmpdirmacro que nomeie o diretório temporário do sistema.
  • TMPDIRé a variável de ambiente canônica para alterar o local dos arquivos temporários. Antes do POSIX, havia outras variáveis ​​usadas, então eu costumo ir com a primeira daquilo ou TMP, TEMPDIRe TEMPisso tem um valor, puncionar e usar o padrão do sistema, se nenhuma delas existir.
  • As funções mkstemp()e tempfile()irão gerar arquivos temporários exclusivos.

Se for negado aos usuários a capacidade de criar arquivos temporários, o sistema está configurado incorretamente ou os administradores não estão deixando claro qual é sua política nessas coisas. Nesses casos, você estaria muito firme ao dizer que seu programa está em conformidade com um padrão de portabilidade bem estabelecido e que seu comportamento pode ser alterado usando as variáveis ​​de ambiente especificadas pelo padrão.

Blrfl
fonte
P_tmpdirnão faz parte da stdio.hdefinição da especificação da linguagem C. Pode ser definido pelo POSIX ou SVID.
Musiphil
1
@musiphil: Como está implícito na resposta (agora esclarecida), ela faz parte do POSIX. (Tecnicamente, é um sistema aberto / Extensão X que POSIX incorporados Ver. Pubs.opengroup.org/onlinepubs/009695399/basedefs/stdio.h.html. )
Blrfl
Concordo plenamente com todos os itens acima. Um bom exemplo são os sistemas Linux com pam_tmpdir- isso define TMPDIRe TMPdeve ser diferente para cada usuário, para robustez e privacidade. Também é útil poder definir TMPDIRum único comando - se você tiver o diretório temporário habitual em um sistema de arquivos RAM para obter velocidade, talvez seja necessário fazer isso para comandos que geram arquivos temporários enormes (como um gigante sort, por exemplo). Não ignore os padrões / convenções que seus usuários esperam!
perfil completo de Toby Speight
Definitivamente, verifique o ambiente quanto à localização de arquivos temporários e nunca codifique / tmp. Como um tmp compartilhado tem problemas de segurança, uma mitigação que eu sempre vi é criar diretórios por usuário / tmp sem permissão de leitura e gravação para mais ninguém. Remove possíveis condições de corrida e ataques de link simbólico.
Zan Lynx
9

O diretório temporário-arquivo é altamente dependente do sistema operacional / ambiente. Por exemplo, um diretório web-servers-temp é separado do os-temp-dir por motivos de segurança.

Sob ms-windows, todo usuário tem seu próprio temp-dir.

você deve usar o createTempFile () para isso, se essa função estiver disponível.

k3b
fonte
1
Lembre-se das limitações ocultas do sistema operacional no Windows. Descobrimos da maneira mais difícil que o número máximo de arquivos em uma pasta era limitado a 65.565. Claro, isso é um monte de arquivos, e com certeza, você nunca deve concebivelmente ter que muitos por aí. Mas você tem certeza de que todos os aplicativos se limpam de maneira oportuna e bem-comportada?
9606 Mike Hofer
Ah, já vi seu comentário tarde demais. Eu acabei de escrever o mesmo acima. BTW, o limite se deve principalmente à mecânica da função GetTimeFileName (), não ao NTFS. O limite de pastas que você mencionou se aplica somente ao FAT32 .
JensG
9

As respostas anteriores, embora corretas, não são válidas para a maioria dos clusters de computadores em grande escala.

Os clusters de computadores nem sempre seguem as convenções padrão das máquinas, geralmente por boas razões, e não faz sentido discutir isso com os administradores de sistemas.

Seu diretório atual está se referindo ao sistema de arquivos central, que é acessado através da rede. Isso não é apenas lento, mas também sobrecarrega o sistema para o resto dos usuários; portanto, você não deve usá-lo, a menos que não esteja escrevendo muito e possa se recuperar se o trabalho falhar.

Os nós de computação têm seu próprio disco rígido, que é o sistema de arquivos mais rápido disponível e o que você deve usar. A documentação do cluster deve informar o que é, normalmente /scratch, /tmp/[jobid]ou alguma variável de ambiente não padrão ( $SNIC_TMPem uma das que eu uso).

Então, o que eu recomendo é torná-lo configurável pelo usuário. Os padrões podem ser os primeiros aos quais você tem acesso de gravação:

  • $TMPDIR
  • tmpfile
  • /tmp
  • .

Mas espere uma baixa taxa de sucesso com essa abordagem e certifique-se de emitir um grande aviso.

Editar: adicionarei outro motivo para forçá-lo a ser definido pelo usuário. Um dos meus clusters foi $TMPDIRdefinido como /scratchgravável pelo usuário e no disco rígido local. Porém, a documentação diz que tudo o que você escreve fora /scratch/[jobid]pode ser excluído a qualquer momento, mesmo no meio da execução. Portanto, se você seguir os padrões e confiar $TMPDIR, encontrará falhas aleatórias, muito difíceis de depurar. Portanto, você pode aceitar $TMPDIR, mas não confiar nele.

Alguns outros clusters têm essa variável configurada corretamente; portanto, você pode adicionar uma opção para confiar explicitamente $TMPDIR; caso contrário, emitir um aviso grande e gordo.

Davidmh
fonte
1
Quais são exatamente as respostas anteriores?
Tulains Córdova
2
Então, o que você está dizendo aqui é que, como alguns clusters que não seguem a etapa trivial de aderir a um padrão bem estabelecido para informar aos programas onde gravar seus arquivos temporários, essa é uma personalização adicional específica de cluster necessária por programa. Chá bem fraco, se você me perguntar.
Blrfl
@Blrfl, você pode acenar os padrões o quanto quiser e escrever um código que adere perfeitamente a eles e sempre trava; você pode tentar lutar com os administradores de sistemas de cada cluster que você usa; ou você pode aceitar sua fé e torná-la configurável. Além disso, no HPC geralmente é necessário adaptar o código às especificidades do cluster (RAM disponível, velocidade relativa dos sistemas de arquivos, implementação MPI, disponibilidade geral de recursos ...), não existe um "tamanho único".
Davidmh
@ Davididmh: Entendido, mas não é o ponto. O padrão o torna configurável de maneira não surpreendente. Se eu levar o código em conformidade conhecido para um cluster em que o padrão não é seguido, tenho que configurá-lo exatamente em um local, como no ponto de entrada. Isso é menos uma coisa no restante do código para auditar, modificar e correr o risco de errar.
Blrfl
1

Para muitos aplicativos, considere colocar arquivos temporários em $XDG_RUNTIME_DIRou $XDG_CACHE_HOME(os outros diretórios XDG são para arquivos não temporários ). Para obter instruções sobre como calculá-las se elas não forem explicitamente transmitidas no ambiente, consulte a especificação XDG basedir ou encontre uma biblioteca que já implemente essa parte.

Observe, no entanto, que $XDG_RUNTIME_DIRé uma nova adição e não há fallback padrão para sistemas mais antigos devido a problemas de segurança.

Se nenhum deles for adequado, então /tmpé o local correto. Você nunca deve assumir que o diretório atual é gravável.

o11c
fonte
-2

É mais uma alternativa, mas você pode desvincular () o arquivo imediatamente após fopen (). Depende do padrão de uso da cource.

Desvincular os arquivos, se possível, ajuda de várias maneiras:

  • arquivo não é visto - o usuário não o vê.
  • arquivo não é visto em outros processos - não há chance de outro processo modificar o arquivo por engano.
  • limpeza fácil se o programa falhar.

Os arquivos devem ser criados em / tmp. Se o usuário não tiver direitos para criar um arquivo, isso significa que o sistema está configurado incorretamente.

Os arquivos não podem ser criados no diretório inicial do usuário. Muitos usuários, como "ninguém", "www-data" e muitos outros, não têm direitos para escrever em seus diretórios pessoais ou são até chroot (). Observe que mesmo no ambiente chroot / tmp ainda existe.

usuario
fonte
Embora isso possa ser uma boa idéia, em geral, isso não ajuda os usuários que estão faltando permissões de gravação no diretório do arquivo deve ser criado no.
5gon12eder
4
Também não responde à pergunta, onde é onde colocar os arquivos temporários.
Blrfl
Eu acredito que minha resposta é de alguma forma importante. Eu editei, provavelmente é mais claro assim.
7776 Nick