GNU/Linux >> Znalost Linux >  >> Linux

Mktemp na Macu nectí $tmpdir?

Všiml jsem si toho již dříve, ale objevilo se to znovu, když jsem odpovídal „Jak přesunout adresář do adresáře se stejným názvem?“:

mktemp obslužný program na macOS se s ohledem na TMPDIR nechová stejně jako obslužný program stejného jména v systému Linux nebo BSD (nebo alespoň OpenBSD). proměnná prostředí.

Chcete-li vytvořit dočasný soubor v aktuálním adresář, mohu obvykle říci

tmdfile=$(TMPDIR=. mktemp)

nebo

tmpfile=$(TMPDIR=$PWD mktemp)

(a podobně pro dočasný adresář s mktemp -d ).

V systému macOS budu muset nástroj donutit, aby používal aktuální adresář tím, že mu dám skutečnou šablonu, jako v

tmpfile=(mktemp ./tmp.XXXXXXXX)

protože pomocí pohodlnějšího tmpfile=$(TMPDIR=. mktemp) by ignoroval TMPDIR proměnnou a vytvořte soubor pod /var/folders/qg/s5jp5ffx2p1fxv0hy2l_p3hm0000gn/T nebo v podobně pojmenovaném adresáři.

Manuál pro mktemp na macOS zmiňuje, že

Pokud -t prefix je dána možnost mktemp vygeneruje řetězec šablony na základě předpony a
_CS_DARWIN_USER_TEMP_DIR konfigurační proměnná, pokud je k dispozici. Záložní umístění, pokud
_CS_DARWIN_USER_TEMP_DIR není k dispozici jsou TMPDIR a /tmp .

V mém systému _CS_DARWIN_USER_TEMP_DIR zdá se, že není nastaveno:

$ getconf _CS_DARWIN_USER_TEMP_DIR
getconf: no such configuration parameter `_CS_DARWIN_USER_TEMP_DIR'

ale např.

tmpfile=$(TMPDIR=. mktemp -t hello)

stále vytváří soubor pod /var/folders/.../ (také při použití $PWD místo . ).

Všiml jsem si toho

$ getconf DARWIN_USER_TEMP_DIR
/var/folders/qg/s5jp5ffx2p1fxv0hy2l_p3hm0000gn/T/

ale to mi moc nepomůže, protože bych nevěděl, jak tuto hodnotu změnit.

MacOS mktemp utilita prý pochází z FreeBSD, které ji zase dostalo z OpenBSD (což muselo být už docela dávno).

Otázka:

Jedná se o chybu (nebo opomenutí) v implementaci mktemp pro macOS? ? Jak změním DARWIN_USER_TEMP_DIR hodnota (nebo _CS_DARWIN_USER_TEMP_DIR zmíněný v manuálu) ze skriptu (ideálně bych ho chtěl zrušit tak, aby $TMPDIR má přednost)?

Přijatá odpověď:

/var/folders/qg/s5jp5ffx2p1fxv0hy2l_p3hm0000gn/

Toto je váš Darwin místní uživatel adresář. Jeho jméno je jednoduše upravené základní 32 kódování zřetězení vašeho MacOS UUID uživatele a vaše uživatelské ID MacOS (BSD). První dvě písmena kódování se používají jako „bucket“ systém, který se snaží udržet velikost adresářů na nízké úrovni. Tyto dva znaky jsou zakódovaných prvních 10 bitů uživatelského UUID, protože v základu 32 je jedna číslice samozřejmě 5 bitů.

Jeho podadresáře jsou vaše lokální temp uživatele a místní mezipaměť uživatele adresáře. Jejich názvy bývaly -Caches- a -Tmp- ale ty byly zkráceny na C a T . Mělo by být zřejmé, že všechna tato jména jsou pevná a neměnná, pokud nechcete změnit své uživatelské ID nebo uživatelské UUID.

Když aplikace volá confstr(_CS_DARWIN_USER_TEMP_DIR,…) , knihovna C se nejprve pokusí zajistit, že máte místní uživatel adresář, pak se pokusí zajistit, že máte lokální temp uživatele adresář v něm.

Související:Linux – Jak přesměrovat provoz mezi síťovými jmennými prostory Linuxu?

Ujistěte se, že máte místního uživatele adresář je netriviální, protože nemáte přístup k zápisu do /var/folders . Existuje tedy dirhelper Mach spouštěcí démon, který běží s oprávněními superuživatele a který bezpečně vytváří tyto adresáře, reagující na Mach IPC volání z aplikací z implementace confstr() v jejich C knihovnách. Vy děláte mít přístup pro zápis do místního uživatele adresář (po vytvoření) a tak knihovny C jen mkdir() přímo jeho potomky, pokud již neexistují.

Pokud se to podaří, mktemp program se nikdy nedívá na hodnotu TMPDIR proměnná prostředí, protože záložní v mktemp kód pochází z volání confstr() k volání getenv() ne naopak. confstr(_CS_DARWIN_USER_TEMP_DIR,…) téměř vždy uspěje. Jeho režimy selhání jsou věci jako dirhelper spuštění démona nelze spustit nebo pokus o vytvoření T podadresář selže s chybou jinou než že adresář již existuje.

Můžete dát něco jiného než adresář jako T , ale to bude pravidelně čištěno dirhelper spusťte démona, který také odstraní věci ve /var/folders . Deaktivace dirhelper spuštění démona způsobí problémy samo o sobě, v neposlední řadě to bude /var/folders nečistí se. Odepřete si oprávnění k zápisu do místního uživatele adresář bude potenciálně kolidovat se všemi ostatními používá to, používá se pro víc než jen T podadresář.

Nejlepší možností (kromě dodání šablony) je vytvořit T symbolický odkaz, ale to ještě zdaleka není dobré, protože to samozřejmě ovlivní všechny vaše spuštěné aplikace, které by ve stejném okamžiku mohly chtít vytvořit dočasný soubor.

Ani DARWIN_USER_TEMP_DIR ani _CS_DARWIN_USER_TEMP_DIR jsou názvy proměnných. Jsou to názvy pro getconf a pro confstr() knihovní funkce, konfiguračního řetězce.


Linux
  1. Proč je to Rm -rf a ne Rmdir -rf?

  2. Vypsáno jádro, ale soubor jádra není v aktuálním adresáři?

  3. Odstraňte pouze soubory v adresáři v adresářích linux NOT

  1. Proč můj symbolický odkaz vytváří soubor a ne složku?

  2. Docker neaktualizuje změny v adresáři

  3. Jak zajistím, aby se obrazovka GNU nespustila v mém domovském adresáři v OS X?

  1. Smazat všechny soubory v adresáři, jejichž jméno neodpovídá řádku v seznamu souborů?

  2. Transmission-daemon se nestahuje v adresáři sledování

  3. SCP – není adresář – Co dělám špatně?