2011-10-20 17 views
13

Come può eseguire uno script di bash anche dopo aver incontrato un'istruzione per cancellarsi? Per esempio, quando mi sono imbattuto test.sh script che conains:Auto cancellazione di script bash

<--some commands--> 
rm test.sh 
<--some more commands--> 

end 

Lo script viene eseguito fino alla fine prima di cancellare se stesso

+3

Quando un'applicazione viene eseguita, il suo codice viene caricato in memoria. Stai semplicemente cancellando il file sul disco, che non influisce sul codice in memoria. –

+1

Presumibilmente l'intero script viene letto in memoria al momento dell'esecuzione e quindi i comandi dopo 'rm test.sh' esistono ancora in memoria per essere eseguiti. – MrMisterMan

+0

Non fa una copia in memoria. Ad esempio, se lo script viene modificato mentre è in esecuzione, eseguirà le modifiche. Questo mi ha fatto venire il mal di testa di recente. Simpatico esempio: questo script a una riga riempirà il tuo disco in breve tempo: 'cat $ 0 >> $ 0'. – Ned

risposta

24

Quello che accade è che bash mantiene il file aperto e rm non farà che si fermano.

Quindi rm chiama la funzione libc "unlink()" che rimuoverà il "link" dall'inode dalla directory in cui si trova. Questo "link" è in realtà un nome file insieme a un numero di inode (puoi vedere inode numeri con ls -i).

L'inode esiste finché i programmi lo aprono.

Si può facilmente verificare questa affermazione come segue:

$ echo read a> ni 
$ bash ni 

mentre in un'altra finestra:

$ pgrep -lf bash\ ni 
31662 bash ni 
$ lsof -p 31662|grep ni 
bash 31662 wmertens 255r REG 14,2   7 12074052 /Users/wmertens/ni 
$ rm ni 
$ lsof -p 31662|grep ni 
bash 31662 wmertens 255r REG 14,2   7 12074052 /Users/wmertens/ni 

Il file è ancora aperto, anche se non è più possibile vederlo in ls. Quindi non è che bash leggi l'intero file - non è davvero andato via fino a quando bash non ha finito con esso.

+1

Ecco perché un programma di aggiornamento non dovrebbe mai modificare i file eseguibili esistenti, ma piuttosto scollegarli, quindi riscrivere la nuova versione. – curiousguy

+0

ok, ma cosa succede se il file viene sovrascritto da un altro processo? Il file è scollegato, quindi conta come "spazio libero", non è vero? –

+0

@G_G sovrascrittura significa semplicemente che la voce di directory indicata dal nome file ora si collega a un altro inode. Finché l'inode originale non viene chiuso da bash, esisterà e sarà usato da bash. – w00t

-1

In realtà, questo fenomeno è specifico per le coperture (come bash), che leggono il file in memoria e quindi eseguirli.

Se si esegue il seguente a.bat: eco YO1 del a.bat eco yo2

Si ottiene il seguente output: C:> a.bat

C:> echo YO1 Yo1

C:> del a.bat Impossibile trovare il file batch.

Questo è per una vostra aspettativa :-)

+1

Questo è falso; La risposta di w00t è corretta. Ho visto personalmente degli errori quando uno script di bash è * modificato * mentre è in esecuzione, indicando che il file viene tenuto aperto e letto. –