Kurze Antwort
Führen Sie das Skript mit sourceoder aus .:
source ./script_name.sh
oder
. ./script_name.sh
Letzteres ist für verschiedene Schalen etwas kompatibler.
Lange Antwort
Diese Frage hebt einen wichtigen Punkt hervor, nämlich dass Shell-Skripte in ihrem eigenen Kontext ausgeführt werden. Betrachten Sie das folgende Shell-Skript, um zu sehen, was dies bedeutet:
#!/bin/bash
cd /
ls
Wenn Sie dies ausführen, erhalten Sie eine Ausgabe wie folgt:
bin boot dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
Sie werden jedoch feststellen, dass Sie sich nach dem Ausführen des Skripts immer noch in dem Verzeichnis befinden, in dem Sie sich vor dem Ausführen befanden: Das cd /Innere des Skripts hat Ihre Sitzung nicht wirklich beeinflusst - es hat nur den Kontext beeinflusst, in dem das Skript ausgeführt wurde, in welchem wird für die Ausführung des Skripts erstellt und bei seiner Rückkehr zerstört.
Der sourceBefehl liest 'Befehle aus dem Dateinamenargument im aktuellen Shell-Kontext und führt sie aus', sodass sich alle darin enthaltenen Befehle cdauf Ihre aktuelle Sitzung auswirken. Wenn Sie das obige Skript ausführen, indem Sie es an übergeben, werden sourceSie feststellen, dass Sie nach der Ausführung im Stammverzeichnis landen.
In diesem Fall besteht das Problem darin, dass der historyBefehl den Verlauf für den aktuellen Shell-Kontext angibt. Der Shell-Kontext, in dem Ihr Skript ohne Verwendung ausgeführt wird, sourcehat keinen Verlauf, sodass nichts in die Ausgabedatei geschrieben wird. Wenn Sie es verwenden source, wird es im richtigen Kontext ausgeführt und funktioniert wie erwartet.
NB: Ist sourceeine Shell eingebaut, kein Programm an sich - in Bash sourceist das gleichbedeutend mit ., aber in einigen Shells .funktioniert nur - habe ich sourcein dieser Antwort verwendet, weil es einfacher zu lesen ist als ., aber für maximale Kompatibilität .sollte verwendet werden.