複数のプラットフォームで正しいtmpディレクトリを見つける


46

作業のために一時ファイルを作成し、それ自体をクリーンアップする必要があるスクリプトがあります。私の質問は、一時ファイルの正しいベースディレクトリを見つけることです。

スクリプトは、Git Bash(Windows)、Solaris、Linux、OSXなどの複数のプラットフォームで動作する必要があります。プラットフォームごとに、優先される一時ディレクトリの表現が異なります。

  • Windows:(%TMP%および場合によっては%TEMP%
  • OSX: $TMPDIR
  • Linux、UNIX:あるはず$TMPDIRですが、私が試した複数のシステムでは設定されていないようです

したがって、私のスクリプトでは、この定型句を追加しました。

if test -d "$TMPDIR"; then
    :
elif test -d "$TMP"; then
    TMPDIR=$TMP
elif test -d /var/tmp; then
    TMPDIR=/var/tmp
else
    TMPDIR=/tmp
fi

これは面倒です。もっと良い方法はありますか?


6
${TMPDIR-/tmp}Unixライクで使用するだけです。TMPDIR(システム、管理者、またはユーザーによって)/tmp一時ファイルに使用しない場合を通知します。
ステファンシャゼル14

回答:


72

一時ファイルを処理するためのもう少しポータブルな方法は、を使用することmktempです。一時ファイルが作成され、パスが返されます。例えば:

$ mktemp
/tmp/tmp.zVNygt4o7P
$ ls /tmp/tmp.zVNygt4o7P
/tmp/tmp.zVNygt4o7P

スクリプトで非常に簡単に使用できます。

tmpfile=$(mktemp)
echo "Some temp. data..." > $tmpfile
rm $tmpfile

manページを読むと、必要に応じてオプションを設定できるはずです。例えば:

  • -d ファイルの代わりにディレクトリを作成します。
  • -u 名前を生成しますが、何も作成しません。

を使用-uすると、一時ディレクトリを非常に簡単に取得できます...

$ tmpdir=$(dirname $(mktemp -u))

詳細についてmktempは、こちらをご覧ください

Mac OS Xに関する編集: Mac OSXシステムを使用したことはありませんが、以下のTyiloのコメントによると、Mac OSX mktempではテンプレート(Linuxのオプション引数)を提供する必要があるようです。引用:

テンプレートには、たとえば、いくつかの「X」が追加された任意のファイル名を指定できます/tmp/temp.XXXX。末尾の「X」は、現在のプロセス番号や一意の文字の組み合わせに置き換えられます。mktempが返すことができる一意のファイル名の数は、提供される「X」の数に依存します。6つの「X」により、mktempは56800235584の1つ(62 ** 6)の可能なファイル名を選択します。

また、manページには、この実装がOpenBSDのmanページに触発されていると書かれていますmktemp。そのため、OpenBSDとFreeBSDのユーザーも同様の相違が見られる場合があります(歴史のセクションを参照)。

おそらくお気づきかもしれませんが、この場合、質問で探している一時ディレクトリを含む完全なファイルパスを指定する必要があります。この小さな問題は、-tスイッチを使用して処理できます。このオプションには引数(prefix)が必要なようですmktemp$TMPDIR、必要なときに依存するように見えます。

全体として、上記と同じ結果を得ることができるはずです...

$ tmpdir=$(dirname $(mktemp tmp.XXXXXXXXXX -ut))

このソリューションを自分でテストすることはできないため、Mac OS Xユーザーからのフィードバックは大歓迎です。


OPは、削除されたコメントでこの問題に対処しました。私はgitbash、シェルインターフェイスを取得する必要があるシステムに答えを提供できないのではないかと心配しています。私は実際に...一時ファイルは、Windowsシステムに保存されている場所を伝えることができないであろう
ジョン・WHスミス

1
それと同じ。クレイジーc:\User\Name\..............\stuff。そして、おそらく100個あります。それでも、一部のLinuxディストリビューションはで同じレベルの狂気に近づいています/var。ちょっと気になっただけ。奇妙な言い方をすれば、それはすべてです-私の経験では、フラストレーションは非常にポータブルであり、利便性はそれほど高くありません。とにかく非常に良い答え。
mikeserv 14

1
1年ほど前に、Win2KからWinXPまで動作するWindows復元ポイントファイルを操作するためのBashスクリプトを作成しました(後のバージョンではその処理方法が異なります)。私のスクリプトは、WINDOWS/TempまたはWindows/Tempその一時ファイルのデフォルトのディレクトリとして使用します。そのディレクトリはWindows 7マシンにも存在します。しかし、私のスクリプトでは、ユーザーはコマンドラインで代替の一時ディレクトリを指定できます。
PM 2リング14

OS Xではテンプレートを提供する必要があるため、これは機能しませんmktemp
ティロ14

1
El Capitan以来、動作するmktempだけです。simple mktempはファイルをmktemp -d返し、ディレクトリを返します。テンプレートは必要ありません。マニュアルはかかわらず、更新されません。
フランクリンゆう

9

より少ない行で同じものを探しているなら...

for TMPDIR in "$TMPDIR" "$TMP" /var/tmp /tmp
do
    test -d "$TMPDIR" && break
done

これを1つで書くことができます。


また、書き込み可能かどうかもテストする必要があります。
frostschutz 14

@janos:他のすべてが失敗した場合、ユーザーに一時ファイルのパスを指定するか、コマンドラインで指定することを許可します。
PM 2リング14

6

あなたがするかもしれない:

: "${TMPDIR:=${TMP:-$(CDPATH=/var:/; cd -P tmp)}}"
cd -- "${TMPDIR:?NO TEMP DIRECTORY FOUND!}" || exit

シェルは、4つの選択肢のいずれかで実行可能ディレクトリを見つけるか、意味のあるエラーで終了する必要があります。それでも、POSIXは$TMPDIR変数を定義します(XCUシステムの場合)

TMPDIR この変数は、一時ファイルを作成する場所を必要とするプログラムで使用できるディレクトリのパス名を表します。

また、/tmpパスが必要です。


1
ここがIMOの唯一の正しい答えです。それは無投票で底に座ってやっていること知らん...
グレアム・

2
@Graeme:多分それがまったく読めないからですか?
ssc

私は賛成しましたが、それを撤回しました-はい、この答えは混乱です、それは有用なトラックにあるようですが、コードスニピットが何をしようとしているのかはまったく明確ではありません-最初の行はコメントであり、2番目の行は1つはエラーです(とにかくbashで)。いくつかの作業を使用できます。
ドンハッチ

ああ、答えの最初のバージョンはより明確でした(実際に実行しようとすると2行目にまだエラーがあります)...そして一連の編集がコードサンプルを完全に破壊したため、今では意味がありません。別のパスまたは2 :-)使用することができます
ドンハッチ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.