一時ファイルは/ tmpまたは現在の作業ディレクトリに保存する必要がありますか?


76

一時ファイルを生成する必要があるプログラムがあります。クラスタマシン用に書かれています。

これらのファイルをシステム全体の一時ディレクトリ(例:)に保存すると/tmp、一部のユーザーは、/ tmpへの適切なアクセス権がないためにプログラムが失敗したと訴えました。しかし、これらのファイルを作業ディレクトリに保存すると、それらのユーザーは、これらの不思議なファイルを見たくないと不満を漏らしました。

どちらがより良い習慣ですか?に保存するの/tmpが正しいアプローチであると主張し、失敗を「意図したとおりに動作する」として防御する必要があります(つまり、適切な許可/アクセスを管理者に依頼します)。


3
プログラムにアクセスできるかどうかを確認し、別の一時ディレクトリが見つからない場合
ラチェットフリーク

24
管理者がアクセス権を台無しにした場合は、間違いなく修正する必要があります。管理者がプログラムに実行権を追加するのを忘れたらどうしますか?
ドックブラウン

7
ほとんどのWindowsシステムでは/ tmpは見つかりませんが、一時ファイルを置く場所を知らせるOS呼び出しがあります。
イアン

28
/tmpUnixライクなシステムにアクセスできない人がいると、設定が正しくありません。スーパーユーザーはのようなことをする必要がありますchmod 1777 /tmp
-musiphil

12
$ TMPDIRが/tmp/、代わりに使用する必要がある以外のパスを指す場合があることに注意してください。回答の一部を参照してください;)
marcelm

回答:


141

一時ファイルは、いくつかの理由でオペレーティングシステムの一時ディレクトリに保存する必要があります。

  • オペレーティングシステムを使用すると、それらのファイルの作成が非常に簡単になりますが、それらの名前は一意になります。

  • ほとんどのバックアップソフトウェアは、一時ファイルを含むディレクトリを認識し、それらをスキップします。現在のディレクトリを使用する場合、バックアップが頻繁に行われると、増分バックアップのサイズに重要な影響を与える可能性があります

  • 一時ディレクトリは別のディスクまたはRAMにあり、読み取り/書き込みアクセスがはるかに高速になります。

  • 一時ファイルは、多くの場合、再起動中に削除されます(RAMディスクにある場合は、単に失われます)。これにより、アプリが常に一時ファイルを正しく削除しない場合(たとえば、クラッシュ後)に無限に成長するリスクが軽減されます。

    ファイルがアプリケーションファイルやユーザーファイルと一緒に保存されている場合、作業ディレクトリから一時ファイルを削除すると、簡単に乱雑になる可能性があります。現在のディレクトリ内に別のディレクトリを作成することでこの問題を軽減できますが、これにより別の問題が発生する可能性があります。

  • 一部のプラットフォームでは、パスの長さすぎる可能性があります。たとえば、Windowsでは、一部のAPI、フレームワーク、およびアプリケーションのパス制限はひどいです。つまり、現在のディレクトリがツリー階層内で既に深く、一時ファイルの名前が長すぎる場合、この制限に簡単に達することができます。

  • サーバーでは、多くの場合、一時ディレクトリの成長の監視はすぐに行われます。別のディレクトリを使用すると、監視されない場合があり、ディスク全体を監視しても、一時ファイルがますます多くの場所を占めることを簡単に把握できません。

アクセス拒否エラーについては、オペレーティングシステムが一時ファイルを作成できるようにしてください。たとえば、オペレーティングシステムは、特定のユーザーに対して、使用されるディレクトリ/tmpまたはC:\Windows\temp使用されるべきでないディレクトリを知っている場合があります。したがって、これらのディレクトリに直接アクセスすると、実際にアクセス拒否エラーが発生する場合があります。

オペレーティングシステムコールを使用している場合でもアクセスが拒否された場合、それは単にマシンの構成が不適切であることを意味します。これはすでにBlrflによって説明されました。マシンを構成するのはシステム管理者次第です。アプリケーションを変更する必要はありません。

一時ファイルの作成は、多くの言語で簡単です。いくつかの例:

  • バッシュ:

    # 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);
    
  • ルビー:

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

PHPやRubyなど、場合によっては、ハンドルが閉じられるとファイルが削除されることに注意してください。これは、言語/フレームワークにバンドルされているライブラリを使用することの追加の利点です。


2
「オペレーティングシステムに一時ファイルを作成させてください」とはどういう意味ですか。たとえば、代わりにfopen("/tmp/mytmpfile", "w");一時ファイルを処理するためにいくつかのシステムコールを作成する必要がありますか?
サイモン

30
@gurka:tmpfile(3)一時ファイルを生成mktemp(3)するために呼び出すか、少なくともファイル名を作成するために呼び出す必要があります。
TMN

3
@TMN:これらはユーザー空間で実行される単なるライブラリ関数であり、オペレーティングシステムによって与えられた許可エラーをバイパスする魔法はありません。
-musiphil

25
@musiphil tmpfileとmktempはどちらも外部変数を使用して一時ファイルのパスを決定します。これらは、/ tmp /以外の別のディレクトリ、おそらくユーザーごとのディレクトリを指すように設定されている可能性があります。/ tmp /にファイル名を手動で作成しようとすると失敗する場合がありますが、tmpfileとmktempは有効なパスを返します。
パイプ

2
@musiphil:私は彼らが許可の問題を修正すると言ったことは一度もありませんでした。私はシステムコールを使用してファイルを作成することに関する彼の質問に答えていました。
TMN

33

/ tmpへの保存が正しいアプローチであると主張し、「意図したとおりに動作する」という障害を防御する必要があります(つまり、適切なアクセス許可を管理者に求める)。

これには標準があり、できることはそれに従うことです。

POSIXには、実行される可能性のある重要なほとんどすべての非メインフレームOSが続きますが、環境によって再構成可能なデフォルト値を使用して、ディレクトリに一意の名前の一時ファイルを作成するための規定があります。

  • C stdio.hヘッダーにはP_tmpdir、システムの一時ディレクトリを指定するマクロをオプションで含めることができます。
  • TMPDIRは、一時ファイルの場所を変更するための標準的な環境変数です。POSIXに先立ち、使用される他の変数があったので、私はそれまたはの最初で行く傾向がありTMPTEMPDIRそしてTEMPそれはパントと、それらのどれもが存在しない場合は、システムのデフォルトを使用して、値を持っています。
  • 機能のユニークな一時ファイルを生成します。mkstemp()tempfile()

ユーザーが一時ファイルを作成する機能を拒否されている場合、システムが誤って構成されているか、管理者がそのようなことに関するポリシーを明確にしていません。そのような場合、プログラムは確立された移植性標準に準拠しており、その動作は標準が指定する環境変数を使用して変更できると言って、非常に確固たる地位にいるでしょう。


P_tmpdirstdio.hC言語仕様で定義されているものの一部ではありません。POSIXまたはSVIDによって定義される場合があります。
-musiphil

1
@musiphil:(明確になった)答えが示すように、それはPOSIXの一部です。(技術的には、POSIXに組み込まれたX / Open System Extensionです。pubs.opengroup.org / onlinepubs / 009695399 / basedefs / stdio.h.htmlを参照してください
Blrfl

上記すべてに完全に同意します。良い例は、以下を備えたLinuxシステムです。pam_tmpdirこれはTMPDIRTMP堅牢性とプライバシーのために、ユーザーごとに異なるように設定されています。TMPDIR単一のコマンドに設定できることも便利です-速度のためにRAMファイルシステムに通常の一時ディレクトリがある場合、巨大な一時ファイルを生成するコマンド(たとえば、巨人など)に対してこれを行う必要があるかもしれませんsort。ユーザーが期待する標準/慣習を無視しないでください!
トビーSpeight

環境で一時ファイルの場所を確実に確認し、/ tmpをハードコーディングしないでください。共有tmpにはセキュリティ上の問題があるため、よく見られる軽減策の1つは、ユーザーごとに/ tmpディレクトリを作成することです。起こりうる競合状態とシンボリックリンク攻撃を取り除きます。
ザンリンクス

9

temp-file-directoryは、オペレーティングシステム/環境に大きく依存しています。たとえば、web-servers-temp dirは、セキュリティ上の理由からos-temp-dirから分離されています。

ms-windowsでは、すべてのユーザーが独自のtemp-dirを持っています。

そのような関数が利用可能な場合、このためにcreateTempFile()を使用する必要があります。


1
Windowsの隠されたOSの制限に注意してください。フォルダー内のファイルの最大数が65,565に制限されるという難しい方法を発見しました。確かに、それは大量のファイルであり、確かに、そのような多くのファイルを配置することは考えられないはずです。しかし、すべてのアプリがタイムリーで行儀の良い方法でそれ自体をクリーンアップすると確信していますか?
マイク

ああ、あなたのコメントを見たのは遅すぎた。上記と同じように書きました。ところで、制限は主にNTFSではなく、GetTimeFileName()関数のメカニズムによるものです。あなたが言及したそのフォルダ制限はFAT32にのみ適用されます
-JensG

9

これまでの答えは正しいものの、ほとんどの大規模なコンピュータークラスターでは無効です。

コンピュータークラスターは、通常、正当な理由により、コンピューターの標準的な規則に従っていない場合があり、システム管理者と議論する意味はありません。

現在のディレクトリは、ネットワーク経由でアクセスされる中央ファイルシステムを参照しています。これは遅いだけでなく、残りのユーザーの負荷もシステムにかけるため、あまり書きすぎない限り使用しないでください。ジョブがクラッシュした場合は回復できます。

コンピューティングノードには独自のハードドライブがあり、これは利用可能な最速のファイルシステムであり、使用すべきものです。クラスタのドキュメントは、一般的に、それが何であるかを教えてくれなければならない/scratch/tmp/[jobid]または(いくつかの非標準的環境変数$SNIC_TMP私が使用するものの一つで)。

そのため、ユーザーが構成できるようにすることをお勧めします。デフォルトは、書き込みアクセス権を持っている最初のものです。

  • $TMPDIR
  • tmpfile
  • /tmp
  • .

しかし、このアプローチでは低い成功率を期待し、大きな太った警告を出すようにしてください。

編集:それを強制的にユーザー設定にする別の理由を追加します。クラスターの1つがに$TMPDIR設定され/scratchています。これは、ユーザーによる書き込みが可能で、ローカルハードドライブ上にあります。しかし、ドキュメントには/scratch/[jobid]、実行の途中であっても、外部で記述したものはいつでも削除できると書かれています。そのため、標準に従い、trust $TMPDIRを使用すると、ランダムなクラッシュが発生し、デバッグが非常に困難になります。ですから、あなたは受け入れるかもしれ$TMPDIRませんが、それを信頼しません。

他の一部のクラスターでは、この変数が適切に構成されているため、明示的に信頼するオプションを追加することができます$TMPDIR


1
正確に前の答えはどれですか?
Tulainsコルドバ

2
つまり、ここであなたが言っているのは、一時ファイルを書き込む場所をプログラムに伝えるための確立された標準に従うという些細な手順を踏まないクラスターがあるため、それはプログラムごとに必要な追加のクラスター固有のカスタマイズだということです。あなたが私に尋ねるとかなり弱いお茶。
Blrfl

@Blrflを使用すると、必要なだけ標準をウェーブし、標準に完全に準拠し、常にクラッシュするコードを作成できます。使用する各クラスターのシステム管理者と戦うことができます。または、自分の信仰を受け入れて構成可能にすることができます。さらに、HPCでは通常、とにかくコードをクラスターの仕様(利用可能なRAM、ファイルシステムの相対速度、MPI実装、リソースの一般的な可用性など)に適合させる必要があり、「すべてに適合するサイズ」はありません。
-Davidmh

@Davidmh:理解しましたが、ポイントではありません。この規格により、驚くことなく構成できます。規格に準拠していないクラスターに既知の適合コードを使用する場合、エントリーポイントなどの正確に1か所に設定する必要があります。残りのコードでは、監査、変更、および間違いのリスクを1つ減らすことができます。
Blrfl

1

多くのアプリケーションでは、一時ファイルを$XDG_RUNTIME_DIRまたはに配置することを検討する必要があります$XDG_CACHE_HOME(他のXDGディレクトリは非一時ファイル用です)。環境で明示的に渡されない場合の計算方法については、XDG basedirの仕様を参照するか、その部分を既に実装しているライブラリを見つけてください。

ただし、これ$XDG_RUNTIME_DIRは新たに追加されたものであり、セキュリティ上の懸念により、古いシステムに標準的なフォールバックはありません。

どちらも適切でない場合/tmpは、正しい場所です。現在のディレクトリが書き込み可能であると想定してはなりません


-2

これは代替手段に似ていますが、fopen()の直後にファイルをunlink()する可能性があります。それはコースの使用パターンに依存します。

ファイルのリンクを解除できる場合は、いくつかの方法で役立ちます。

  • ファイルが表示されません-ユーザーは表示されません。
  • ファイルは他のプロセスからは見えません-他のプロセスが誤ってファイルを変更する可能性はありません。
  • プログラムがクラッシュした場合の簡単なクリーンアップ。

ファイルは/ tmpに作成する必要があります。ユーザーがそこにファイルを作成する権限を持っていない場合、これはシステムが誤って設定されていることを意味します。

ユーザーのホームディレクトリにファイルを作成できません。「nobody」、「www-data」などの多くのユーザーは、ホームディレクトリに書き込む権限を持っていないか、chroot()されています。chroot環境でも/ tmpが存在することに注意してください。


これは一般的には良い考えかもしれませんが、ファイルが作成されるディレクトリへの書き込み権限がないユーザーには役立ちません
。– 5gon12eder

4
また、一時ファイルを置く場所である質問には答えません。
Blrfl

私の答えはなんとなく重要だと思います。私は編集しましたが、おそらくこの方法の方が明確です。
ニック
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.