Znalezienie poprawnego katalogu tmp na wielu platformach


46

Mam skrypt, który musi utworzyć pliki tymczasowe do pracy i posprzątać po sobie. Moje pytanie dotyczy znalezienia odpowiedniego katalogu podstawowego dla plików tymczasowych.

Skrypt musi działać na wielu platformach: Git Bash (Windows), Solaris, Linux, OSX. Na każdej platformie preferowany katalog tymczasowy jest wyrażany inaczej:

  • Windows: %TMP%(i ewentualnie %TEMP%)
  • OSX: $TMPDIR
  • Linux, UNIX: powinien być, $TMPDIRale wydaje się być rozbrojony na wielu systemach, których próbowałem

Więc w swoim skrypcie dodałem ten szablon:

if test -d "$TMPDIR"; then
    :
elif test -d "$TMP"; then
    TMPDIR=$TMP
elif test -d /var/tmp; then
    TMPDIR=/var/tmp
else
    TMPDIR=/tmp
fi

To wydaje się zbyt nudne. Czy jest lepszy sposób?


6
Po prostu użyj ${TMPDIR-/tmp}na Unix-like. TMPDIRjest tam (przez system, administratora lub użytkownika), aby powiedzieć, kiedy nie należy używać /tmpdo plików tymczasowych.
Stéphane Chazelas,

Odpowiedzi:


72

Nieco bardziej przenośnym sposobem obsługi plików tymczasowych jest użycie mktemp. Stworzy pliki tymczasowe i zwróci dla ciebie ich ścieżki. Na przykład:

$ mktemp
/tmp/tmp.zVNygt4o7P
$ ls /tmp/tmp.zVNygt4o7P
/tmp/tmp.zVNygt4o7P

Możesz użyć go w skrypcie dość łatwo:

tmpfile=$(mktemp)
echo "Some temp. data..." > $tmpfile
rm $tmpfile

Czytając stronę podręcznika, powinieneś być w stanie ustawić opcje zgodnie z własnymi potrzebami. Na przykład:

  • -d tworzy katalog zamiast pliku.
  • -u generuje nazwę, ale niczego nie tworzy.

Za pomocą -umożesz łatwo odzyskać katalog tymczasowy za pomocą ...

$ tmpdir=$(dirname $(mktemp -u))

Więcej informacji na temat mktempjest dostępnych tutaj .

Edycja dotycząca Mac OS X: Nigdy nie korzystałem z systemu Mac OSX, ale zgodnie z komentarzem Tyilo poniżej, wygląda na tomktemp , że Mac OSX wymaga dostarczenia szablonu (który jest opcjonalnym argumentem w systemie Linux). Cytowanie:

Szablon może być dowolną nazwą pliku z dołączoną na przykład pewną liczbą „X” /tmp/temp.XXXX. Końcowe „X” są zastępowane bieżącym numerem procesu i / lub unikalną kombinacją liter. Liczba unikalnych nazw plików, które mktemp może zwrócić, zależy od podanej liczby „X”; sześć „X” spowoduje, że mktemp wybierze 1 z 56800235584 (62 ** 6) możliwych nazw plików.

Strona podręcznika mówi również, że ta implementacja jest zainspirowana stroną podręcznika OpenBSD dla mktemp. Podobną rozbieżność można zatem zaobserwować również dla użytkowników OpenBSD i FreeBSD (patrz sekcja Historia ).

Teraz, jak zapewne zauważyłeś, wymaga to podania pełnej ścieżki pliku, w tym katalogu tymczasowego, którego szukasz w pytaniu. Ten mały problem można rozwiązać za pomocą -tprzełącznika. Chociaż wydaje się, że ta opcja wymaga argumentu ( prefix), wydaje się, że mktempopiera się ona w $TMPDIRrazie potrzeby.

Podsumowując, powinieneś być w stanie uzyskać taki sam wynik jak powyżej, używając ...

$ tmpdir=$(dirname $(mktemp tmp.XXXXXXXXXX -ut))

Wszelkie uwagi od użytkowników systemu Mac OS X byłyby bardzo mile widziane, ponieważ nie jestem w stanie samodzielnie przetestować tego rozwiązania.


PO rozwiązał ten problem w skreślonym komentarzu; Obawiam się, że nie mogę udzielić odpowiedzi dla systemów, które wymagają gitbashinterfejsu powłoki, stąd moje „nieznacznie”. Nie byłbym w stanie powiedzieć, gdzie przechowywane są pliki tymczasowe w systemie Windows ...
John WH Smith,

1
to samo. Szaleni c:\User\Name\..............\stuff. I jest ich prawdopodobnie 100. Mimo to niektóre dystrybucje linuksowe zbliżają się do tego samego poziomu szaleństwa /var. Byłem tylko ciekawy. Uderzyło mnie to, jak dziwnie to ujmuję - z mojego doświadczenia frustracja jest bardzo przenośna, a wygoda mniej. W każdym razie bardzo dobra odpowiedź.
mikeserv

1
Mniej więcej rok temu napisałem skrypt Bash do manipulowania plikami Windows Restore Point działającymi na Win2K aż do WinXP (późniejsze wersje obsługują to inaczej). Mój skrypt używa WINDOWS/Templub Windows/Tempjako domyślny katalog dla swoich plików tymczasowych; ten katalog istnieje również na komputerach z systemem Windows 7. Ale mój skrypt pozwala użytkownikowi podać alternatywny katalog temp w wierszu poleceń.
PM 2,

Nie działałoby to w systemie OS X, ponieważ musisz dostarczyć szablon do mktemp.
Tyilo

1
Od El Capitan mktemppo prostu działa: simple mktempzwraca plik i mktemp -dzwraca katalog; nie wymaga szablonów. Instrukcja nie jest aktualizowany chociaż.
Franklin Yu

9

Jeśli szukasz tego samego w mniejszej liczbie wierszy ...

for TMPDIR in "$TMPDIR" "$TMP" /var/tmp /tmp
do
    test -d "$TMPDIR" && break
done

Możesz to napisać w jednym.


Prawdopodobnie powinieneś również sprawdzić, czy jest to zapis.
frostschutz

@janos: A jeśli wszystko inne zawiedzie, poproś użytkownika o podanie ścieżki do plików tymczasowych lub zezwolenie na określenie jej w wierszu polecenia.
PM 2,

6

Możesz zrobić:

: "${TMPDIR:=${TMP:-$(CDPATH=/var:/; cd -P tmp)}}"
cd -- "${TMPDIR:?NO TEMP DIRECTORY FOUND!}" || exit

Powłoka powinna albo znaleźć katalog wykonywalny w jednej z 4 alternatyw, albo wyjść ze znaczącym błędem. Mimo to POSIX definiuje $TMPDIRzmienną (dla systemów XCU) :

TMPDIR Ta zmienna reprezentuje nazwę ścieżki do katalogu udostępnianego programom, które potrzebują miejsca do tworzenia plików tymczasowych.

Wymaga również /tmpścieżki.


1
To jedyna słuszna odpowiedź tutaj IMO. Nie wiem, co robi siedzenie na dole bez głosów ...
Graeme

2
@Graeme: może dlatego, że jest całkowicie nieczytelny?
ssc

Głosowałem, ale potem wycofałem - tak, ta odpowiedź to bałagan, Wydaje się, że jest to przydatna ścieżka, ale wcale nie jest jasne, co próbuje zrobić fragment kodu - pierwsza linia to komentarz, a druga jeden to błąd (w każdym razie bash). Przydałby się trochę pracy.
Don Hatch,

Och, rozumiem, pierwsza wersja odpowiedzi była wyraźniejsza (nadal błąd w drugiej linii, jeśli faktycznie próbujesz ją uruchomić) ... a następnie seria zmian całkowicie zniszczyła próbkę kodu, więc teraz jest to nonsens. Przydałby się kolejny lub dwa podania :-)
Don Hatch
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.