Bash trap na função, mas executada quando o script inteiro sai?

1

Estou me perguntando se algo assim é possível.

function get_temp_dir() {
    local tmp_dir=$(mktemp -d)
    trap "{
           rm -r $tmp_dir
       }" EXIT
    echo $tmp_dir
}

temp=$(get_temp_dir)

# I'd like to $temp for the duration of this script, and deleted
# when this current scope ends, not when the function scope ends.

Eu vi outros scripts atingirem o mesmo efeito usando matrizes globais com uma única função de interceptação que enumera a matriz e faz algo com ela. Eu gostaria de evitar isso se eu puder.

Eu também estou ciente de que eu poderia apenas criar um diretório tmp e criar vários diretórios tmp dentro do diretório. No entanto, eu gostaria de usar essa abordagem porque é amplamente utilizável para outras coisas, como montar / desmontar.

Alguma ideia? Agradecemos antecipadamente.

edit: Então, o TRAP é chamado quando o shell script termina, no entanto, na minha pergunta original, eu estava usando um subshell ( $() ). Consegui trabalhar depois de reformatar meu código para isso:

#!/usr/bin/env bash

function get_temp_dir() {
    local tmp_dir=$(mktemp -d)
    trap "{
           rm -r $tmp_dir
       }" EXIT
    retval=$tmp_dir
}

get_temp_dir
tmp_dir=$retval

ls $tmp_dir
    
por Paul Knopf 11.05.2018 / 19:50

2 respostas

1

Acho que você está procurando o sinal RETURN :

[...] If a SIGNAL_SPEC is EXIT (0) ARG is executed on exit from the shell.
[...] If a SIGNAL_SPEC is RETURN, ARG is executed each time a shell function or a script run by the . or source builtins finishes executing.

Exemplo:

$ bash
$ trap "echo shell exiting" EXIT
$ fn() { trap "echo function exiting" RETURN; }
$ fn
function exiting
$ (fn)
function exiting
$ value=$(fn); echo "$value"
function exiting
$ exit
shell exiting

e, germaine para a pergunta:

$ f2() { 
    local tmp=$(mktemp)
    trap 'rm "$tmp"' RETURN
    echo "$tmp"
    date >> "$tmp"
    cat "$tmp"
}
$ f2
/tmp/tmp.MHpI20X0a1
Fri May 11 14:29:01 EDT 2018
$ ls -l /tmp/tmp.MHpI20X0a1
ls: cannot access '/tmp/tmp.MHpI20X0a1': No such file or directory
    
por 11.05.2018 / 20:25
0

Em meus scripts, geralmente faço algo assim no início, nos casos em que escrevo arquivos temporários:

scratch="$(mktemp -d)"
trap 'rm -fr "$scratch"' EXIT

Quaisquer arquivos ou diretórios reais podem ser escritos pelo nome (por exemplo, mkdir $scratch/foo; touch $scratch/foo/bar ) ao longo do script, mas o serviço de limpeza é resolvido imediatamente após o término do script com o trap .

    
por 11.05.2018 / 19:59