これは以前にも気づきましたが、「同じ名前のディレクトリにディレクトリを移動するにはどうすればよいですか?」と答えていたときに、再び表示されました。
mktemp
macOSのユーティリティは、TMPDIR
に関して、LinuxまたはBSD(または少なくともOpenBSD)の同じ名前のユーティリティと同じように動作しません。 環境変数。
現在に一時ファイルを作成するには ディレクトリ、私は通常言うことができます
tmdfile=$(TMPDIR=. mktemp)
または
tmpfile=$(TMPDIR=$PWD mktemp)
(同様に、mktemp -d
を使用する一時ディレクトリの場合 。
macOSでは、
のように、実際のテンプレートを指定して、ユーティリティに現在のディレクトリを使用させる必要があります。tmpfile=(mktemp ./tmp.XXXXXXXX)
より便利なtmpfile=$(TMPDIR=. mktemp)
を使用しているため TMPDIR
を無視します 変数を作成し、/var/folders/qg/s5jp5ffx2p1fxv0hy2l_p3hm0000gn/T
の下にファイルを作成します。 または同様の名前のディレクトリにあります。
mktemp
のマニュアル macOSでそれについて言及しています
-t prefix
の場合 オプションが指定されています、mktemp
プレフィックスと_CS_DARWIN_USER_TEMP_DIR
に基づいてテンプレート文字列を生成します 可能な場合は構成変数。
_CS_DARWIN_USER_TEMP_DIR
の場合のフォールバックの場所TMPDIR
はご利用いただけません および/tmp
。
私のシステムでは、_CS_DARWIN_USER_TEMP_DIR
設定されていないようです:
$ getconf _CS_DARWIN_USER_TEMP_DIR
getconf: no such configuration parameter `_CS_DARWIN_USER_TEMP_DIR'
ただし、例:
tmpfile=$(TMPDIR=. mktemp -t hello)
引き続き/var/folders/.../
の下にファイルを作成します ($PWD
を使用する場合も .
。
気づいています
$ getconf DARWIN_USER_TEMP_DIR
/var/folders/qg/s5jp5ffx2p1fxv0hy2l_p3hm0000gn/T/
しかし、この値を変更する方法がわからないため、これはあまり役に立ちません。
macOS mktemp
ユーティリティはFreeBSDから来ていると言われており、FreeBSDはOpenBSDから来ています(かなり前のことです)。
質問:
これはmktemp
のmacOS実装のバグ(または省略)ですか? ? DARWIN_USER_TEMP_DIR
を変更するにはどうすればよいですか 値(または_CS_DARWIN_USER_TEMP_DIR
マニュアルで言及されている)スクリプト内から(理想的には、$TMPDIR
になるように設定を解除したいと思います 優先されます)?
承認された回答:
/var/folders/qg/s5jp5ffx2p1fxv0hy2l_p3hm0000gn/
これはダーウィンのローカルユーザーです ディレクトリ。その名前は、MacOS User UUIDの連結のベース32エンコーディングを変更したものです。 およびMacOS(BSD)ユーザーID。エンコーディングの最初の2文字は、ディレクトリサイズを低く抑えるための「バケット」システムとして使用されます。これらの2文字は、ユーザーUUIDのエンコードされた最初の10ビットです。これは、Base32では1桁がもちろん5ビットであるためです。
そのサブディレクトリは、ユーザーのローカル温度です。 およびユーザーローカルキャッシュ ディレクトリ。以前は-Caches-
でした。 および-Tmp-
しかし、それらはC
に短縮されています およびT
。ユーザーIDまたはユーザーUUIDを変更する意思がない限り、これらの名前はすべて固定されており、変更できないことは明らかです。
アプリケーションがconfstr(_CS_DARWIN_USER_TEMP_DIR,…)
を呼び出すとき 、Cライブラリは最初にユーザーローカルがあることを確認しようとします 次に、ディレクトリで、 user local temp があることを確認しようとします その中のディレクトリ。
ローカルユーザーがいることを確認します /var/folders
への書き込みアクセス権がないため、ディレクトリは重要です。 。したがって、dirhelper
があります スーパーユーザー権限で実行され、これらのディレクトリを安全に作成し、confstr()
の実装内からのアプリケーションからのMachIPC呼び出しに応答するMach起動デーモン 彼らのCライブラリで。あなたは ユーザーローカルへの書き込みアクセス権を持っている ディレクトリ(作成後)なので、Cライブラリはmkdir()
まだ存在しない場合は、その子を直接使用します。
これが成功した場合、mktemp
プログラムはTMPDIR
の値を見ることはありません mktemp
でのフォールバックのため、環境変数 のコードは、confstr()
を呼び出したものです。 getenv()
の呼び出し その逆ではありません。 confstr(_CS_DARWIN_USER_TEMP_DIR,…)
ほとんどの場合成功します。その失敗モードは、dirhelper
のようなものです。 デーモンを起動できない、またはT
を作成しようとしている サブディレクトリが以外のエラーで失敗する ディレクトリがすでに存在していること。
T
としてディレクトリ以外のものを置くことができます 、ただし、これはdirhelper
によって定期的にクリーンアップされます デーモンを起動します。これは、/var/folders
内のものを削除するものでもあります 。 dirhelper
を無効にする デーモンを起動すると、それ自体に問題が発生します。特に、/var/folders
が問題になります。 掃除されていません。 ローカルユーザーへの書き込み権限を拒否する ディレクトリは、他のすべてのに干渉する可能性があります それの使用、それは単なるT
以上に使用されています サブディレクトリ。
(テンプレートを提供する以外の)最善のオプションは、T
を作成することです。 シンボリックリンクですが、これは、一時ファイルを作成したいと思う可能性のある、実行中のすべてのアプリケーションに影響を与えるため、まだ良いとは言えません。
どちらのDARWIN_USER_TEMP_DIR
また、_CS_DARWIN_USER_TEMP_DIR
変数名です。これらは、getconf
の名前です。 ユーティリティおよびconfstr()
構成文字列のライブラリ関数。