it-swarm-eu.dev

Oprava nebo alternativa pro mktemp v OS X

Dívám se na bash skript, který napsal někdo jiný, který používá mktemp:

TEMP=`mktemp --directory`

Tento řádek však na mém počítači nefunguje (OS X 10.6).

Jak mohu tento řádek opravit tak, aby byl kompatibilní s platformou cross-un * x-like-platform? EDIT: Dostatečný by byl i alternativní příkaz.

78
soundly_typed

Toto je to, co jsem nakonec použil, abych spolehlivě vytvořil dočasný adresář, který funguje jak na Linuxu, tak na Darwinu (všechny verze před Mac OS X 10.11), bez pevného kódování $TMPDIR Nebo /tmp:

mytmpdir=$(mktemp -d 2>/dev/null || mktemp -d -t 'mytmpdir')

Pozadí:

Příkaz GNU mktemp nevyžaduje žádné argumenty. Plain mktemp bude fungovat a vytvoří dočasný soubor v dočasném adresáři systému.

Plain mktemp -d Vytvoří adresář místo souboru, což byste chtěli použít v Linuxu.

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

Ve výchozím nastavení GNU mktemp používá pro název podadresáře (nebo souboru) šablonu tmp.XXXXXXXXXX. K přizpůsobení této šablony lze použít volbu -t použitý.

OSX mktemp nemá žádnou výchozí šablonu a vyžaduje specifikaci šablony. Bohužel, kde GNU mktemp bere šablonu jako možnost -t, V OSX se to předává jako poziční argument. Místo toho má mktemp OSX možnost -t, Což znamená něco jiného. Možnost -t v OSX je zdokumentována jako „předpona“ pro šablonu. Rozšíří se na {prefix}.XXXXXXXX, takže k ní automaticky přidává X (např. mktemp -d -t example mohl vytvořit example.zEJZWCTQ v dočasném adresáři).

Překvapilo mě, když jsem zjistil, že v mnoha Linuxových prostředích je $TMPDIR Ve výchozím nastavení ne. Mnoho programů CLI jej po nastavení podporuje, ale stále potřebuje výchozí nastavení pro /tmp. To znamená, že předání $TMPDIR/example.XXXXXXXX Na mktemp nebo mkdir je nebezpečné, protože to může produkovat /example.XXXXXXXX V kořenovém adresáři lokálního disku (kvůli $ TMPDIR je deaktivováno a stává se prázdný řetězec).

V OSX je vždy nastaven $TMPDIR A (alespoň ve výchozím Shell) není nastaven na /tmp (Což je symbolický odkaz na /private/tmp), Ale na /var/folders/dx/*****_*************/T. Takže cokoli, co děláme pro OSX, by mělo toto výchozí chování ctít.

Závěrem je to, co jsem nakonec použil pro spolehlivě vytvořil dočasný adresář, který funguje jak pro Linux, tak pro Darwin (Mac OS X), aniž by jsme tvrdě kódovali buď $TMPDIR Nebo /tmp:

mytmpdir=$(mktemp -d 2>/dev/null || mktemp -d -t 'mytmpdir')

První část je pro Linux. Tento příkaz selže v Darwinu (Mac OS X) s chybovým stavovým kódem 1, Který odpoví „use: ...“. Proto ignorujeme stderr a místo toho spustíme variantu Mac. Předpona mytmpdir se používá pouze v počítačích Mac (kde je třeba tuto možnost nastavit).

117
Timo Tijhof

Musíte zadat šablonu. mktemp -d /tmp/foo.XXXX měl by pracovat. Nikdy jsem neviděla --directory. The -- naznačuje, že se jedná o příponu GNU).

15
Kyle Jones

Změna --directory to -d. První z nich je GNU-ism, ale GNU mktemp from coreutils také podporuje -d. mktemp v OS X je stejné jako u BSD, takže -d by měl být docela přenosný mezi systémy, které skutečně dodávají program mktemp.

9
James Sneeringer
temp_dir="$(mktemp -q -d -t "$(basename "$0").XXXXXX")"
  • mktemp pro BSD (včetně OSX ) vyžaduje šablonu, ale umožňuje jakýkoli počet Xs v šabloně.
  • (GNU) mktemp pro Linux nevyžaduje šablonu, pokud je však předloha zadána, musí být počet Xs 6.

Všimněte si, že -t je zastaralé pro GNU mktemp , takže kód budoucnosti by byl lepší

temp_dir="$(mktemp -q -d -t "$(basename "$0").XXXXXX" 2>/dev/null || mktemp -q -d)"
5
go2null