Kann ich eine Bash-Skriptdatei (.sh) während der Ausführung ändern?


28

Angenommen, ich habe ein Skript script.sh, dessen Ausführung einige Zeit in Anspruch nimmt. Ich führe es aus ./script.sh. Während es in einem Terminalfenster läuft, ändere ich die Datei script.sh. Wird dies Auswirkungen auf den bereits laufenden Prozess haben?

Nach der Änderung führe ich die geänderte Datei aus, sodass jetzt zwei Prozesse ausgeführt werden. Ist das okay?


Antworten:


36

Wenn Sie Änderungen an Ihrem Skript vornehmen, nehmen Sie die Änderungen auf der Festplatte (dem permanenten Speicher) vor. Wenn Sie das Skript ausführen, wird das Skript in Ihren Arbeitsspeicher (RAM) geladen.

Die Änderungen, die Sie am Skript vornehmen, wirken sich nicht auf das ausgeführte Skript aus. Sie führen die Version aus, die Sie ausgeführt haben, bevor Sie diese Änderungen vorgenommen haben.

Wenn Sie das geänderte Skript jedoch erneut ausführen, ohne die zuvor ausgeführte Instanz zu beenden, gibt es zwei Instanzen des Skripts: eine mit den Änderungen und die alte.

Seien Sie gewarnt, dass die vom Skript verwendeten und geänderten Ressourcen Konflikte verursachen. Wenn Sie beispielsweise eine Datei mithilfe des Skripts ändern, kann das später ausgeführte Skript diese Datei nicht zum Schreiben öffnen und kann nicht ordnungsgemäß ausgeführt werden.

Update: Vielen Dank an den registrierten Benutzer, der mich auf eine bessere Antwort auf Unix.stackexchange.com hingewiesen hat.

Abhängig von der Größe des Skripts und des betreffenden Compilers / Interpreters wird das Skript teilweise / vollständig geladen. Wenn das Skript nicht vollständig geladen ist, wirken sich die Änderungen, die Sie an Ihrem Skript vornehmen, auf die ausgeführte Instanz aus, sobald der Teil des Skripts in den Speicher geladen wurde.

Es wird daher nicht empfohlen, Ihr Skript auf der Festplatte zu ändern, die derzeit für eine unvorhersehbare Ausgabe ausgeführt wird: Beenden Sie zuerst die ausgeführte Instanz, ändern Sie dann Ihr Skript und führen Sie das Skript erneut aus.


11
Nicht die perfekte Antwort, lesen Sie unix.stackexchange.com/q/121013/55673
Registrierter Benutzer

@registereduser: oh ja, diese Frage hat mich nur an meinen OS-Unterricht erinnert. Bearbeitet meine Antwort, sobald ich meine Hände auf meinem Desktop (im
Moment

Ich denke, dass es für kurze Skripte kein Problem geben sollte.
Becko

1
Als ich dies mit bash v3.2.48 versuchte (siehe hier ), pufferte es nicht über das Zeilenende hinaus (und schlug fehl, als ich das Skript während der Ausführung änderte). Ich habe gerade mit bash v4.3.0 erneut getestet und es hat das gesamte (kurze) Skript gepuffert. Also ... ich würde nicht mit einem bestimmten Verhalten rechnen.
Gordon Davisson

1
@RegisteredUser Nicht bei allen Versionen von bash - siehe das Beispiel, das ich verlinkt habe.
Gordon Davisson

4

Ich werde etwas hinzufügen, von dem ich denke, dass es in den anderen Antworten nicht gesagt wurde. Viel hängt davon ab, wie Sie die Datei bearbeiten. Wenn Sie echo "stuff" >filevon der Shell (einer anderen Instanz) aus arbeiten, wird die Datei in der Tat überschrieben, denke ich. Aber wenn Sie die Datei zum Beispiel mit bearbeiten emacsund dann speichern, wird dies nicht passieren. Stattdessen benennt der Editor die alte Datei in einen Sicherungsnamen um (möglicherweise wird die vorherige Sicherung tatsächlich entfernt) und schreibt den geänderten Pufferinhalt dann als neue Datei mit dem (jetzt freigegebenen) alten Namen . Da die Schale (oder ein anderer Interpreter) Lesen des Drehbuchs wird mit ziemlicher Sicherheit die Datei öffnen , nur einmal, ist es danach unabhängig von den Verbleib der DateinameLiest nur die physische Festplattendatei (identifiziert durch die Inode-Nummer), die dem Dateinamen zum Zeitpunkt des Öffnens zugeordnet war. Selbst wenn das Skript in Blöcken gelesen wird (was die einfachste Lösung wäre, wenn Sie gepufferte Text-E / A verwenden), werden weiterhin die Zeilen aus der alten Instanz der Datei gelesen, die sich durch Ihre Bearbeitung wahrscheinlich nicht ändern wird.


+1 Ich benutze Sublime Text als Editor. Weißt du, ob es auch die Datei umbenennt, wie emacs?
Becko

1
Ich denke, die meisten Redakteure würden ein Umbenennungsschema verwenden (auch wenn sie keine Sicherungsversionen behalten sollten), um das Risiko zu vermeiden, dass bei einem Absturz während des Schreibvorgangs überhaupt keine intakte Version des Texts übrig bleibt. Sie können mit "ls -i" (das die Inode-Nummern anzeigt) überprüfen, wie sich Ihr Editor verhält.
Marc van Leeuwen

1

Dies muss aktualisiert werden, die obigen Antworten sind jetzt nur teilweise korrekt:

Bei der aktuellen Version von bash führt das Ändern eines Skripts auf der Festplatte, während es ausgeführt wird, dazu, dass bash versucht, die Änderungen in den Speicher zu laden und diese im ausgeführten Skript zu übernehmen. Wenn Ihre Änderungen nach der aktuell ausgeführten Zeile eintreten, werden die neuen Zeilen geladen und ausgeführt. Aber dies ist eine Vermutung von Bash und es kann richtig oder falsch sein.

Der bessere Weg, dies zu tun, ist die folgende Abfolge von Aktionen: 1) Laden Sie das Skript in den Speicher 2) Löschen Sie das Skript von der Festplatte 3) Schreiben Sie ein neues Skript auf die Festplatte, indem Sie zuerst die Festplattenversion löschen. Die Speicherversion verliert ihre Verknüpfungen Wenn Sie in Schritt 3 eine neue Version angeben, wird von bash nicht versucht, die neuen Inhalte in die Speicherversion zu laden.


0

Die Antwort von @jobin ist im Allgemeinen richtig, aber ich füge noch einige andere Antworten hinzu, die je nach dem, was Sie tun möchten, auf den Punkt kommen können.

Wenn Sie das Skript ändern möchten und wissen möchten, dass es sicher ist, dann möchten Sie in eine neue Datei schreiben, nicht in die vorhandene. Die neue Datei kann sich jedoch an der Stelle befinden, an der sich die alte befand. Schreiben Sie Ihre neue Version in eine neue Datei und mvverschieben Sie sie dann mit über die alte. Die ersetzte Datei existiert noch, sie ist nur nicht aus dem Verzeichnis verlinkt. Ihr laufendes Skript kann es weiterhin verwenden, und wenn dieses Skript seine Dateizugriffsnummer schließt, weiß das System, dass es die Datei sicher bereinigen kann (sofort oder zu einem späteren Zeitpunkt).

Wenn Sie das Verhalten des Skripts im laufenden Betrieb ändern möchten, haben Sie ein schwierigeres Problem. Ich gehe davon aus, dass Sie es in den Code des Skripts einbauen müssen. Bash-Skripte können mit Signalen umgehen (z. B. können sie etwas abfangen kill -USR1 [pid]), und ein Skript könnte dann durch Neuladen von Code reagieren. Vielleicht können Sie Funktionen in die Nähe Ihrer Wünsche bringen, aber ohne zu wissen, wonach Sie suchen, sehe ich keinen guten Grund, dies zu tun, und ich vermute, wenn Sie etwas in dieser Komplexität tun möchten, möchten Sie wahrscheinlich eine anspruchsvollere Programmiersprache, um es zu tun.

Wenn Sie das Verhalten eines laufenden Skripts hacken möchten, das nicht in diesem Sinne geschrieben wurde, haben Sie Pech. Ich würde zögern, eine Programmieraufgabe für unmöglich zu erklären, aber wenn Sie die Ressourcen und Fähigkeiten für diese Art von Aufgabe hätten, würden Sie hier vermutlich nicht nachfragen.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.