web-dev-qa-db-ja.com

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

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

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

どちらが良い習慣ですか? /tmpは適切なアプローチであり、失敗を「意図したとおりに機能する」ものとして保護します(つまり、適切な許可/アクセスを管理者に依頼します)?

79
HelloWorld

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

  • オペレーティングシステムはそれを作成します名前が一意になるようにしながら、これらのファイルを作成するのは非常に簡単です

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

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

  • 一時ファイルは、再起動中に削除されることがよくあります(それらがramdiskにある場合、それらは単に失われます)。これにより、アプリが一時ファイルを常に正しく削除しない場合(クラッシュ後など)にinfinite Growthのリスクを軽減します。

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

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

  • サーバーでは、一時ディレクトリの増加の監視はすぐに実行されることがよくあります。別のディレクトリを使用する場合、それは監視されない可能性があり、ディスク全体を監視しても、ますます多くの場所を占める一時ファイルであることを簡単に理解するのに役立ちません。

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

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

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

  • 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:

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    ...
    char temp_file[] = "/tmp/tmp.XXXXXX";
    int fd = mkstemp(temp_file);
    dprintf(fd, "Hello World!!!\n");
    close(fd);
    
  • 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
    

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

141

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

これには標準があり、あなたができる最善のことはそれらに準拠することです。

POSIXには、メインフレーム以外のほとんどすべての重要なOSがあり、それに遭遇する可能性が高いため、環境によって再構成できるデフォルト値を使用して、一意の名前の一時ファイルをディレクトリに作成するための準備があります。

  • C _stdio.h_ヘッダーには、オプションで、システムの一時ディレクトリを指定する_P_tmpdir_マクロを含めることができます。
  • TMPDIRは、一時ファイルの場所を変更するための標準的な環境変数です。 POSIX以前は、他の変数が使用されていたため、最初の値、または値を持つTMPTEMPDIRおよびTEMPを使用する傾向があり、それらが存在しない場合のシステムデフォルト。
  • mkstemp()およびtempfile()関数は、一意の一時ファイルを生成します。

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

33
Blrfl

上記の回答は正しいですが、ほとんどの大規模コンピュータークラスターでは有効ではありません。

コンピュータクラスタは、通常は正当な理由により、マシンの標準的な規則に従っていない場合があり、sysadminsとそれを話し合う意味はありません。

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

コンピューティングノードには独自のハードドライブがあります。これは、利用可能な最速のファイルシステムであり、使用する必要があります。クラスターのドキュメントには、通常は/scratch/tmp/[jobid]、またはいくつかの非標準の環境変数(使用している変数の1つでは$SNIC_TMP)が記載されています。

だから、私がお勧めするのは、ユーザーが設定できるようにすることです。デフォルトは、書き込みアクセス権を持つ最初のものにすることができます。

  • $TMPDIR
  • tmpfile
  • /tmp
  • .

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

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

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

9
Davidmh

一時ファイルのディレクトリは、オペレーティングシステム/環境に大きく依存します。たとえば、セキュリティ上の理由から、web-servers-temp dirはos-temp-dirとは別です。

Ms-windowsでは、すべてのユーザーが独自の一時ディレクトリを持っています。

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

9
k3b

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

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

どちらも適切でない場合は、/tmpが適切な場所です。現在のディレクトリが書き込み可能であると決して仮定しないでください。

1
o11c

/ tmpへの適切なアクセス権がなかった

「適切なアクセス」が何を意味するのかは明らかではありません。 /tmp/xxx: Permission deniedのようなものですか?

他の人が指摘したように、/tmpの下にはすべて一意の名前を付ける必要があるため、プログラムが各ユーザーに対して/tmp/xxxというファイルを使用している場合、最初のユーザーのみがそれを使用できます。他のすべてのユーザーは、最初のユーザーが所有するファイルに書き込もうとしているため、プログラムは失敗します。

ただし、これまで他の回答で言及されていないことは、/tmp、自分のホームディレクトリ、または現在のディレクトリではなく/var/tmpを使用することには十分な技術的な理由があります。

一部のシステムでは、RAMディスクとして/tmpが設定されています。これには、3つの主な利点があります。

  • RAMディスクは、永続的なストレージデバイス上のどのディスクよりもはるかに高速です。
  • RAMディスクはSSDメモリを損なうことはありません。SSDメモリは、存続期間中に処理できる書き込み数に制限があります。
  • 一時ファイルは、それを作成したプログラムが自動的にクリーンアップせずに終了した場合でも、自動的に削除されます。 (/var/tmpにも当てはまります。RAMディスクにすることはできません。)
0
Ray Butterworth