Posso modificare un file di script bash (.sh) mentre è in esecuzione?


28

Supponiamo che io abbia uno script script.sh, che richiede del tempo per essere eseguito. I eseguirlo, ./script.sh. Mentre è in esecuzione in una finestra del terminale, modifico il file script.sh. Questo avrà qualche effetto sul processo già in esecuzione?

Dopo averlo modificato, eseguo il file modificato, quindi ora ho due processi in esecuzione. Va bene?


Risposte:


36

Quando si apportano modifiche allo script, si apportano le modifiche sul disco (hard disk - la memoria permanente); quando si esegue lo script, lo script viene caricato nella memoria (RAM).

Pertanto, le modifiche apportate allo script non influiranno sullo script in esecuzione, ma eseguirà la versione eseguita prima di apportare tali modifiche.

Tuttavia, quando esegui di nuovo lo script modificato senza terminare l'istanza precedentemente in esecuzione, ci saranno due istanze dello script: uno con le modifiche e quello precedente.

Tieni presente che le risorse utilizzate e modificate dallo script saranno in conflitto. Ad esempio, se si modifica un file utilizzando lo script, lo script che verrà eseguito in seguito non sarà in grado di aprire quel file per la scrittura e non verrà eseguito correttamente.

Aggiornamento: grazie all'utente registrato per avermi indicato una risposta migliore su Unix.stackexchange.com.

A seconda della dimensione dello script e del compilatore / interprete in questione, lo script viene caricato parzialmente / completamente. Pertanto, se lo script non è completamente caricato, le modifiche apportate allo script si rifletteranno sull'istanza in esecuzione una volta caricata la parte dello script in memoria.

Pertanto, non è consigliabile modificare lo script sul disco che è attualmente in esecuzione per output imprevedibile: innanzitutto interrompere l'istanza in esecuzione, quindi modificare lo script e quindi eseguire nuovamente lo script.


11
Non è la risposta perfetta, leggi unix.stackexchange.com/q/121013/55673
Utente registrato

@registereduser: oh sì, quella domanda mi ha appena ricordato le mie lezioni sul sistema operativo. Modificherò la mia risposta non appena avrò le mani sul desktop (sul mio telefono in questo momento)
jobin

Immagino che per gli script brevi non ci dovrebbero essere problemi.
becko,

1
Quando l'ho provato con bash v3.2.48 (vedi qui ), non ha bufferato oltre la fine della riga (e ha fallito male quando ho modificato lo script mentre veniva eseguito). Ho appena eseguito nuovamente il test con bash v4.3.0 e ha bufferizzato l'intero script (breve). Quindi ... non contare su alcun comportamento particolare.
Gordon Davisson,

1
@RegisteredUser Non con tutte le versioni di bash - vedi l'esempio che ho collegato.
Gordon Davisson,

4

Aggiungerò qualcosa che penso non sia stato detto nelle altre risposte. Molto dipende da come si modifica il file. Fare echo "stuff" >filedalla shell (un'altra istanza) sovrascriverà davvero il file, penso. Ma se si modifica il file con per esempio emacse poi si salva, ciò non accadrà. Invece qui l'editor rinomina il vecchio file con un nome di backup (forse rimuovendo effettivamente il backup precedente), quindi scrive il contenuto del buffer modificato come nuovo file con il vecchio nome (ora libreated) . Poiché la shell (o un altro interprete) che legge lo script aprirà quasi sicuramente il file una sola volta, da allora in poi è indipendente dalla posizione del nome del file, continua a leggere il file del disco fisico (identificato dal numero di inode) che era associato al nome del file al momento dell'apertura. Quindi, anche se legge lo script in blocchi (che sarebbe la soluzione più semplice se si utilizza l'I / O di testo bufferizzato), continuerebbe a leggere le righe dalla vecchia istanza del file, che probabilmente non cambierà con la modifica.


+1 Sto usando Sublime Text come editor. Sai se anche questo rinomina il file, come emacs?
becko,

1
Penso che la maggior parte degli editor utilizzerebbe uno schema di ridenominazione (anche se non dovrebbero conservare le versioni di backup) per evitare il rischio che se si verificasse un arresto anomalo durante il processo di scrittura, nessuna versione intatta del testo rimarrebbe affatto. Puoi controllare con "ls -i" (che mostra i numeri di inode) quale sia il comportamento del tuo editor.
Marc van Leeuwen,

1

questo deve essere aggiornato, le risposte sopra sono ora solo parzialmente corrette:

con la versione corrente di bash, la modifica di uno script su disco durante l'esecuzione farà sì che bash "provi" a caricare le modifiche in memoria e ad accettarle nello script in esecuzione. se le modifiche vengono dopo la riga attualmente in esecuzione, le nuove righe verranno caricate ed eseguite. ma, questa è un'ipotesi di bash e potrebbe essere corretta o sbagliata.

il modo migliore per farlo è la seguente sequenza di azioni: 1) caricare lo script in memoria 2) eliminare lo script dal disco 3) scrivere un nuovo script sul disco eliminando prima la versione del disco, la versione della memoria perde i collegamenti ad essa in modo che quando si fornisce una nuova versione nel passaggio 3, non verrà effettuato alcun tentativo da parte di bash di caricare i nuovi contenuti nella versione di memoria.


0

La risposta di @ jobin è generalmente corretta, ma aggiungerò altre risposte che potrebbero essere al punto a seconda di ciò che vuoi fare.

Se vuoi cambiare lo script e vuoi sapere che è sicuro, allora vuoi scrivere in un nuovo file, non in quello esistente, Il nuovo file può trovarsi dove si trovava quello vecchio. Scrivi la tua nuova versione in un nuovo file, quindi usala mvper spostarla in posizione sopra quella precedente. Il file che è stato sostituito esiste ancora, non è semplicemente collegato dalla directory. Lo script in esecuzione può continuare a usarlo e quando lo script chiude il suo handle di file, il sistema sa che può ripulire il file in modo sicuro (immediatamente o in un secondo momento).

Se vuoi comportarti al volo con il comportamento dello script, hai un problema più difficile. Mi aspetto che dovresti inserirlo nel codice dello script. Gli script Bash possono gestire i segnali (ad esempio possono catturare qualcosa di simile kill -USR1 [pid]) e uno script potrebbe quindi rispondere ricaricando un po 'di codice. Quindi forse puoi ottenere funzionalità vicine a quello che vuoi, ma senza sapere cosa stai cercando, non vedo una buona ragione per farlo, e sospetto che se vuoi fare qualcosa di così complesso, probabilmente vuoi un più sofisticato linguaggio di programmazione per farlo.

Se vuoi hackerare il comportamento di uno script in esecuzione che non è stato scritto pensando a questo, allora sei sfortunato. Esiterei a considerare impossibile qualsiasi attività di programmazione, ma se avessi le risorse e le competenze per questo tipo di attività, presumibilmente non te lo chiederesti qui.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.