2010-03-18 11 views
9

Ho bisogno di una nuova directory temporanea per fare un po 'di lavoro in uno script di shell. Quando il lavoro è finito (o se uccido il lavoro a metà strada), voglio che lo script ritorni alla vecchia directory di lavoro e cancelli quella temporanea. In Ruby, potrebbe essere il seguente:Operazione temporanea in una directory temporanea nello script di shell

require 'tmpdir' 

Dir.mktmpdir 'my_build' do |temp_dir| 
    puts "Temporary workspace is #{temp_dir}" 
    do_some_stuff(temp_dir) 
end 

puts "Temporary directory already deleted" 

Quale sarebbe il miglior modo per farlo in uno script Bash?

Ecco la mia attuale implementazione. Qualche idea o suggerimento?

here=$(pwd) 
tdir=$(mktemp -d) 
trap 'return_here' INT TERM EXIT 
return_here() { 
    cd "$here" 
    [ -d "$tdir" ] && rm -rf "$tdir" 
} 

do_stuff # This may succeed, fail, change dir, or I may ^C it. 
return_here 
+0

È possibile utilizzare 'cd -' per tornare alla precedente directory. In questo modo non devi salvare il nome della vecchia directory. Un'altra opzione potrebbe essere l'uso di pushd/popd. – JayM

+0

Ho memorizzato esplicitamente la directory per dare a 'do_stuff' la libertà di cambiare directory, cambiare la coda pushd, ecc. Comunque nel mio caso so che' do_stuff' non usa pushd/popd quindi sarebbe un'implementazione molto più bella! – JasonSmith

+0

Non mi fiderei di 'cd -' (lo script potrebbe avere' cd'-ed-multiplo prima dell'esecuzione del trap). –

risposta

15

Qui si va:

#!/bin/bash 
TDIR=`mktemp -d` 

trap "{ cd - ; rm -rf $TDIR; exit 255; }" SIGINT 

cd $TDIR 
# do important stuff here 
cd - 

rm -rf $TDIR 

exit 0 
+2

È possibile aggiungere EXIT alla trappola e non sarà necessario eseguire esplicitamente il comando 'rm'. –

+0

Grazie! Questo è un buon modello. Ho aggiornato la mia domanda con la mia versione. Però non sono uscito da 255 così. – JasonSmith

1

Il solito programma di utilità di farti una directory temporanea è mktemp -d (e l'opzione -p consente di specificare una directory di prefisso).

Non sono sicuro che "Voglio catturare" fosse una domanda, ma bash non ti lascia intrappolare segnali (sorpresa!) trap - consulta la documentazione.

+0

Grazie. So come usare i componenti. Sto chiedendo in giro per i modi preferiti della gente di metterli tutti insieme. – JasonSmith

1

Supponendo mktemp -d restituisce un percorso relativo, vorrei dimenticare $here e fare questo, invece:

tdir= 
cleanup() { 
    test -n "$tdir" && test -d "$tdir" && rm -rf "$tdir" 
} 
tdir="$(pwd)/$(mktemp -d)" 
trap cleanup EXIT 
trap 'cleanup; exit 127' INT TERM 

# no need to call cleanup explicitly, unless the shell itself crashes, the EXIT trap will run it for you