これは以前にも気づきましたが、「同じ名前のディレクトリにディレクトリを移動するにはどうすればよいですか?」と答えていたときに、再び表示されました。
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() 構成文字列のライブラリ関数。