OS Xのmktempの修正または代替


73

私は誰かが書いたbashスクリプトを見ていますmktemp

TEMP=`mktemp --directory`

ただし、この行は私のマシンでは動作しません(OS X 10.6)。

この行を修正して、un-x * -like-platform互換になるようにしますか?編集:代替コマンドでも十分でしょう。

回答:


109

以下は、LinuxとDarwin(Mac OS X 10.11より前のすべてのバージョン)の両方で動作する一時ディレクトリを、ハードコーディング$TMPDIRもせずに確実に作成するために使用したものです/tmp

mytmpdir=`mktemp -d 2>/dev/null || mktemp -d -t 'mytmpdir'`

バックグラウンド:

GNU mktempコマンドには引数は必要ありません。Plain mktempは動作し、システムの一時ディレクトリに一時ファイルを作成します。

Plain mktemp -dはファイルの代わりにディレクトリを作成します。これはLinuxで使用したいものです。

(gnu-coreutils)$ man mktemp
> ..
> If DIR is not specified, uses $TMPDIR if set, else /tmp.
> ..

デフォルトでは、GNU mktempはtmp.XXXXXXXXXXサブディレクトリ(またはファイル)の名前にテンプレートを使用します。このテンプレートをカスタマイズするには、-tオプションを使用できます。

OSXのmktempにはデフォルトのテンプレートがなく、テンプレートを指定する必要があります。残念ながら、GNU mktempがテンプレートを-tオプションとして使用する場合、OSXではこれは位置引数として渡されます。代わりに、OSXのmktempには、-t他の何かを意味するオプションがあります。-tOSX のオプションは、テンプレートの「プレフィックス」として文書化されています。に展開される{prefix}.XXXXXXXXため、Xが自動的に追加されます(たとえば、tempディレクトリにmktemp -d -t example作成できますexample.zEJZWCTQ)。

多くのLinux環境で$TMPDIRは、デフォルトで設定されていないことに驚きました。多くのCLIプログラムは設定時にサポートしていますが、それでものデフォルトが必要です/tmp。これは$TMPDIR/example.XXXXXXXX、mktempまたはmkdirに渡すことは、ローカルディスクのルートディレクトリで 生成される可能性があるため、危険であることを意味します/example.XXXXXXXX($ TMPDIRが設定されず、空の文字列になるため)。

OSXでは、$TMPDIRは常に設定され、(少なくともデフォルトのシェルでは)に設定されていません/tmp(これはへのシンボリックリンクです/private/tmp)が、に設定されてい/var/folders/dx/*****_*************/Tます。したがって、OSXに対して行うことはすべて、そのデフォルトの動作を尊重する必要があります。

結論として、次は私がするために使用してしまったものです確実にLinuxとダーウィンの両方で動作する一時ディレクトリの作成のいずれかのハードコーディングせずに、(マックOS X)の$TMPDIR/tmp

mytmpdir=`mktemp -d 2>/dev/null || mktemp -d -t 'mytmpdir'`

最初の部分はLinux用です。このコマンドは、ダーウィン(Mac OS X)では1「usage:...」で応答するエラーステータスコードで失敗します。そのため、stderrを無視して、代わりにMacバリアントを実行します。mytmpdirプレフィックスのみを(そのオプションを設定する必要がある)は、Mac上で使用されています。


12
すごくかっこいい。OS Xの異なる動作が煩わしいこともあります。
therealmarv

6
@therealmarvいつも言っておきたい。
ニキータヴォルコフ

10
私はちょうど走ったmktemp -dOS X 10.11.5エルキャピタンに、それが期待通りに働いていた:file $(mktemp -d)/var/folders/j4/htlnmbf97vlcdszj7_x8g0vh4k3_fp/T/tmp.JXmsrQnL: directory
ヒース国境

2
うん。このJust Worked™であることに驚きました。
ヒース国境

1
また、mktemp -d -t 'mytmpdir'Linuxで実行した場合(mktempfromでテスト済みcoreutils 8.26)、期待どおりに動作します。

15

テンプレートを提供する必要があります。 mktemp -d /tmp/foo.XXXX動作するはずです。私は見たことがありません--directory--それはGNUの拡張であることを示唆しています。


6
$TMPDIR利用可能なときに使用する場合は、を実行しますmktemp -d "${TMPDIR:-/tmp}"/foo.XXXX。これはMacではbashで、Debianではダッシュで動作するため、移植性があるようです。
トムアンダーソン

9

に変更--directory-dます。前者はGNU主義ですが、mktempcoreutilsのGNU もサポートしています-dmktempOS Xでは、BSDと同じであるので、-d実際に出荷するシステムの中ではかなり移植する必要がありますmktempプログラムを。


試したところmktemp -d、動作しません。
気づき。

1
カイルは完全な答えを持っています。mktempOS X上では、テンプレートが必要です。使用しているスクリプトは、GNU規則を前提としています。GNU規則では、指定されていない場合はデフォルトのテンプレートが使用されます。
ジェームズ・スニーリンガー

問題は、XXXXXOS Xが互換性のあるテンプレートフラグがあるかどうかわからない場合、unix がテンプレートで提供されることを期待しているということです。
user3467349

2
mktempOS X 10.11.5でEl Capitanは私のために働きますfile $(mktemp -d)::/var/folders/j4/htlnmbf97vlcdszj7_x8g0vh4k3_fp/T/tmp.JXmsrQnL: directory
ヒースの境界線

4
temp_dir="$(mktemp -q -d -t "$(basename "$0").XXXXXX")"
  • mktempBSD(OSXを含む)にはテンプレートが必要ですが、テンプレートX内のsはいくつでも許可されます。
  • (GNU)mktempLinuxの場合、テンプレートは必要ありませんが、テンプレートが指定されている場合、Xs の数は6でなければなりません。

これ-tGNUmktempでは推奨されないため、より将来性のあるコードは次のようになります。

temp_dir="$(mktemp -q -d -t "$(basename "$0").XXXXXX" 2>/dev/null || mktemp -q -d)"
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.