Можно ли перехватить выход / возврат функции? Для программы, которую я мог сделать

trap -- "clean_this" EXIT

Это выполнит функцию clean_this при выходе из программы. Я хотел бы сделать что-то в этом роде при выходе из функции.

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

myfunc &
wait $!

Я выполняю функцию в подоболочке, и я хотел бы перехватить ее выход / возврат. Это возможно?


EDIT1

Вот моя цель

У меня есть один скрипт для управления временными файлами:

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

Вот мой основной сценарий:

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)

Я называю основной сценарий:

$ 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

Я проверяю временные файлы:

$ 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

Временные файлы, объявленные в subshell , теряются из списка при выходе из программы. Я хотел бы удалить их в идеале в конце функции. Либо мне нужно специально удалить их перед выходом из функции, это легко и стоит мне еще одну строчку:

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

Но я хотел бы знать, существует ли элегантный способ их автоматического удаления (временных файлов, созданных в subshells), как я это делал с trap s при выходе из программы.

Итак, мой вопрос: возможно ли это сделать? Какие могут быть альтернативы?

1 ответ1

1

Подоболочки наследуют окружающую среду или ее часть. Похоже, что когда вы выполняете функцию в подоболочке, вам не нужно экспортировать переменные (сравните: нет необходимости в экспорте при запуске функций в подоболочке). Могут быть случаи, когда вам нужно export но давайте сосредоточимся на вашем примере.

Ваш подход некорректен и его будет сложно поддерживать, потому что наследование идет в одну сторону. Каждый (mfunc) наследует tmp_tmp_files и работает со своей собственной копией массива. Нет способа изменить исходные tmp_tmp_files используемые в основном скрипте. Поэтому основной скрипт не может очистить все, он просто не обладает достаточным количеством информации.

Если вы решите очистить функцию subhelled, вам нужно будет обратить внимание и отделить временные файлы функции от временных файлов основного скрипта. Преждевременное удаление последнего может привести к сбою сценария.

Альтернативный подход: временный каталог

  1. Вместо создания массива создайте каталог и запомните его путь. Сделайте это один раз в начале и export если вам нужно:

    tempdir=$(mktemp -d mscript.XXXXXXXXXX)
    
  2. Создайте каждый временный файл во временном каталоге, например так:

    tempfile=$(mktemp -p "$tempdir")
    
  3. В конце удалите весь каталог, независимо от того, были ли определенные файлы созданы основным сценарием или подоболочкой, или даже какой-то сторонней программой. Вы можете использовать ловушку для выполнения этого шага. Просто:

    rm -r "$tempdir"
    

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .