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

74

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

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

Qual é uma prática melhor? Devo insistir que salvar em /tmp é a abordagem correta e defender qualquer falha como "trabalhar como pretendido" (isto é, solicitar ao administrador permissão / acesso adequados)?

    
por SmallChess 05.04.2016 / 13:40
fonte

6 respostas

137

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

  • O sistema operacional torna muito fácil criar esses 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, isso poderá ter um efeito importante no tamanho dos backups incrementais se os backups forem feitos com frequência.

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

  • Os arquivos temporários geralmente são excluídos durante a reinicialização (se estiverem em um ramdisk, eles serão simplesmente perdidos). Isso reduz o risco de crescimento infinito se seu aplicativo nem sempre estiver removendo 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 confusa se os arquivos forem armazenados junto 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, frameworks e aplicativos são terríveis , o que significa que você pode acessar facilmente esses limite se o diretório atual já estiver na 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 pode não ser monitorado e monitorar o disco inteiro não ajudará a descobrir facilmente que são os arquivos temporários que ocupam cada vez mais espaço.

Quanto ao acesso negado, certifique-se de permitir que o sistema operacional crie um arquivo temporário para você. O sistema operacional pode, por exemplo, saber que, para um determinado usuário, um diretório diferente de /tmp ou C:\Windows\temp deve ser usado; assim, acessando esses diretórios diretamente, você pode de fato encontrar um erro de acesso negado.

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

Criar arquivos temporários é simples em muitos idiomas. Alguns exemplos:

  • Bash:

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

    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);
    
  • Ruby:

    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 no Ruby, o arquivo é removido quando o identificador é fechado. Esse é um benefício adicional de usar as bibliotecas incluídas no idioma / estrutura.

    
por 05.04.2016 / 13:46
fonte
33

Should I insist saving to /tmp is the right approach and defend for any failure as "working as intended" (ie. ask your admin for proper permission access)?

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

O POSIX, que é seguido por praticamente todos os SOs que não são mainframes de qualquer significado que você possa encontrar, tem provisões para criar arquivos temporários de nome único em um diretório usando valores padrão que podem ser reconfigurados pelo ambiente :

  • O cabeçalho C stdio.h pode, opcionalmente, incluir uma macro P_tmpdir que nomeia o diretório temporário do sistema.
  • TMPDIR é a variável de ambiente canônico para alterar a localização de arquivos temporários. Antes do POSIX, havia outras variáveis usadas, então eu tenho a tendência de ir com o primeiro disso ou TMP , TEMPDIR e TEMP que tem um valor, punindo e usando o padrão do sistema se nenhum deles existir. / li>
  • As funções mkstemp() e tempfile() geram arquivos temporários exclusivos.

Se for negado a seus usuários a capacidade de criar arquivos temporários, o sistema estará mal configurado ou os administradores não deixarão claro qual é a política deles em relação a isso. Nesses casos, você estaria em terreno 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 pela norma.

    
por 05.04.2016 / 15:02
fonte
9

O diretório temp-file é altamente dependente do sistema operacional / ambiente. Por exemplo, um diretório web-servers-temp é separado do os-temp-dir por razões de segurança.

Em ms-windows, todo usuário possui seu próprio temp-dir.

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

    
por 05.04.2016 / 14:10
fonte
9

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

Clusters de computadores nem sempre seguem as convenções padrão para 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 coloca cargas no sistema para o restante dos usuários, portanto, você não deve usá-lo, a menos que não esteja escrevendo muito e possa recuperá-lo 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_TMP em um dos que eu uso).

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

  • $TMPDIR
  • tmpfile
  • /tmp
  • .

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

Editar: adicionarei outro motivo para forçá-lo a ser definido pelo usuário. Um dos meus clusters tem $TMPDIR definido como /scratch , que é gravável pelo usuário e no disco rígido local. Mas, a documentação diz que qualquer coisa que você escreva fora de /scratch/[jobid] pode ser excluída a qualquer momento, mesmo no meio da execução. Então, se você seguir os padrões e confiar em $TMPDIR , você encontrará travamentos aleatórios, muito difíceis de depurar. Então, você pode aceitar $TMPDIR , mas não confiar.

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

    
por 06.04.2016 / 09:48
fonte
1

Para muitos aplicativos, você deve considerar a colocação de arquivos temporários em $XDG_RUNTIME_DIR ou $XDG_CACHE_HOME (os outros diretórios XDG são para arquivos não temporários). Para obter instruções sobre como calculá-las, caso elas não sejam explicitamente passadas no ambiente, consulte as especificações baseadas em XDG a> 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 preocupações com segurança.

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

    
por 07.04.2016 / 01:49
fonte
-2

Isto é mais como uma alternativa, mas você pode desvincular () o arquivo imidiatamente depois de fopen (). Depende do padrão de uso de cortesia.

Desvinculando os arquivos, se isso puder ser feito, ajuda de várias maneiras:

  • o arquivo não é visto - o usuário não o vê.
  • O arquivo
  • não é visto de 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 o arquivo, isso significa que o sistema está configurado incorretamente.

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

    
por 06.04.2016 / 19:37
fonte