Jak niezawodnie usunąć wszystkie pliki tymczasowe utworzone w skrypcie?

0

Czy można uwięzić wyjście / powrót funkcji? Dla programu, który mógłbym zrobić

trap -- "clean_this" EXIT

Spowoduje to wykonanie funkcji clean_thispo wyjściu z programu. Chciałbym zrobić coś takiego podczas wychodzenia z funkcji.

function myfunc() {
  echo "I'm a function"
}

myfunc &
wait $!

Wykonuję tę funkcję w podpowłoce i chciałbym uwięzić jej wyjście / powrót. Czy to jest możliwe?


EDYCJA 1

Oto mój cel

Mam jeden skrypt do zarządzania plikami tymczasowymi:

cat tempfiles.sh

## List of temp files
tmp_tmp_files=()

## Adds a file to the list of temp files
function tmp_add_file() {
  tmp_tmp_files+=("$1")
}

## Resets the list of temp files
function tmp_reset_files() {
  tmp_tmp_files=()
}

## Removes the list of temp files 
function tmp_rm_all() {
  rm -f "${tmp_tmp_files[@]}"
}

## Removes all temp files on exit and sigint
trap "tmp_rm_all" EXIT SIGINT

Oto mój główny skrypt:

cat mscript.sh

source tempfiles.sh

## ## Creates a temp file and writes in it
mfunc() {
  local tempfile=$(mktemp)
  tmp_add_file $tempfile
  echo "something" >> $tempfile
  echo "($BASHPID) - tempfiles: ${tmp_tmp_files[@]}"
}

## Creates a temp file in main shell
mfunc

## Creates a temp file in a subshell
(mfunc)

Nazywam skrypt główny:

$ bash mscript.sh 
(92250) - tempfiles: /var/folders/9k/h6hn75090_n8z0kythwmwqp96_0t2m/T/tmp.oRlUxEBj
(92254) - tempfiles: /var/folders/9k/h6hn75090_n8z0kythwmwqp96_0t2m/T/tmp.oRlUxEBj /var/folders/9k/h6hn75090_n8z0kythwmwqp96_0t2m/T/tmp.s1iIvtpq

Sprawdzam pliki tymczasowe:

$ cat /var/folders/9k/h6hn75090_n8z0kythwmwqp96_0t2m/T/tmp.oRlUxEBj
cat: /var/folders/9k/h6hn75090_n8z0kythwmwqp96_0t2m/T/tmp.oRlUxEBj: No such file or directory

$ cat /var/folders/9k/h6hn75090_n8z0kythwmwqp96_0t2m/T/tmp.s1iIvtpq 
something

Pliki tymczasowe zadeklarowane w subshellsą tracone z listy podczas wychodzenia z programu. Chciałbym, aby zostały idealnie usunięte na końcu funkcji. Albo muszę je specjalnie usunąć przed opuszczeniem funkcji, jest to łatwe i kosztuje mnie jeszcze jedną linię:

mfunc() {
  local tempfile=$(mktemp)
  tmp_add_file $tempfile1
  echo "something" >> $tempfile
  echo "tempfiles: ${tmp_tmp_files[@]}"
  ## Process things...
  rm $tempfile1
}

Ale chciałbym wiedzieć, czy istnieje elegancki sposób na ich subshellsautomatyczne usunięcie (pliki tymczasowe utworzone w ), tak jak robię to trapprzy wychodzeniu z programu.

Moje pytanie brzmi: czy można to zrobić? Jakie mogą być jakieś alternatywy?

kaligne
źródło
Co próbujesz osiągnąć? Funkcja umieszczona w tle może wywoływać inną funkcję, więc należy myfuncwywoływać clean_thisna samym końcu. Lub przywołaj ich jak { myfunc ; clean_this ; } &. Czy naprawdę potrzebujesz pułapki?
Kamil Maciorowski
Dzięki za odpowiedź. Tutaj zredagowałem moje pytanie i napisałem swój cel. Na pewno mogę uniknąć pułapek, ale odkąd zacząłem z nich korzystać, jeśli mogę zrobić to, co chcę w łatwy sposób ... Dlaczego nie
kaligne

Odpowiedzi:

2

Podkładki dziedziczą środowisko lub jego część. Wygląda na to, że kiedy wykonujesz funkcję w podpowłoce, nie musisz eksportować swoich zmiennych (porównaj: Nie ma potrzeby eksportowania podczas uruchamiania funkcji w podpowłoce ). Mogą zaistnieć przypadki, w których musisz, exportale skupmy się na swoim przykładzie.

Twoje podejście jest wadliwe i będzie trudne do utrzymania, ponieważ dziedziczenie idzie w jedną stronę. Każdy (mfunc)dziedziczy tmp_tmp_filesi działa z własną kopią tablicy. Nie ma mowy, żeby mógł zmodyfikować oryginał tmp_tmp_filesużyty w głównym skrypcie. Dlatego główny skrypt nie może wyczyścić wszystkiego, po prostu nie ma wystarczającej ilości informacji.

Jeśli wybierzesz czyszczenie z funkcji podpowłokowej, musisz zwrócić uwagę i odróżnić pliki tymczasowe funkcji od plików tymczasowych skryptu głównego. Przedwczesne usunięcie tego ostatniego może spowodować awarię skryptu.

Alternatywne podejście: katalog tymczasowy

  1. Zamiast tworzyć tablicę, utwórz katalog i zapamiętaj jego ścieżkę. Zrób to raz na początku, a exportjeśli potrzebujesz:

    tempdir=$(mktemp -d mscript.XXXXXXXXXX)
  2. Utwórz każdy plik tymczasowy w katalogu tymczasowym, tak jak to:

    tempfile=$(mktemp -p "$tempdir")
  3. Na koniec usuń cały katalog, bez względu na to, czy określone pliki zostały utworzone przez główny skrypt, podpowłokę, a nawet jakiś zbłąkany program innej firmy. Do wykonania tego kroku możesz użyć pułapki. Po prostu:

    rm -r "$tempdir"
Kamil Maciorowski
źródło
dzięki, to właśnie robię na teraz. Rozumiem, że nie ma sposobu, aby uruchomić cokolwiek, gdy tylko funkcja się zatrzyma. Dobrze?
kaligne
@ user3298319 Nie wiem na pewno. Tak się złożyło, że twoje pytanie było problemem XY i odpowiedziałem, aby rozwiązać twój rzeczywisty problem. Zmieniłem także tytuł, więc teraz nie jest użyteczny dla użytkowników zainteresowanych pułapkami; jest to przydatne w temacie plików tymczasowych. Chodzi mi o to: to pytanie ewoluowało. Jeśli chcesz zbadać pułapki, możesz zadać kolejne pytanie i wyjaśnić, że pytasz z ciekawości. Może to nie być dobrze odebrane. Witryna koncentruje się na rozwiązywaniu praktycznych problemów, a użytkownicy zwykle przekazują ci odpowiednie narzędzia.
Kamil Maciorowski