2016-08-02 13 views
1

Ich versuche, ein Befehlszeilentool bash zu schreiben, das unmittelbar nach der Installation verwendet werden kann, d. H. In der Shell, in der das Installationsskript aufgerufen wurde. Läßt install-script.sh sagen (entworfen für Ubuntu) sieht so aus:Bash-Skript zur Aktualisierung der Umgebung der übergeordneten Shell abrufen

# Get the script's absolute path: 
pushd `dirname $0` > /dev/null 
SCRIPTPATH=`pwd` 
popd > /dev/null 

# Add lines to bash.bashrc to export the environment variable: 
echo "SCRIPT_HOME=${SCRIPTPATH}" >> /etc/bash.bashrc 
echo "export SCRIPT_HOME" >> /etc/bash.bashrc 

# Create a new command: 
cp ${SCRIPTPATH}/newcomm /usr/bin 
chmod a+x /usr/bin/newcomm 

Die Idee ist, dass der neue Befehl newcomm verwendet den SCRIPT_HOME Umgebungsvariable das Hauptskript zu verweisen - die auch in SCRIPTPATH ist:

exec "${SCRIPT_HOME}/main-script.sh" 

Jetzt wurde die aktualisierte bash.bashrc noch nicht in die Parent-Shell geladen. Schlimmer noch, ich kann nicht source es aus dem Skript - die in einer untergeordneten Shell ausgeführt wird. Die Verwendung von export, um SCRIPT_HOME in der übergeordneten Shell zu ändern, wäre im besten Fall ein Problem mit dem Channel-Taping, aber selbst dies ist unmöglich. Beachten Sie außerdem, dass das Installationsskript unter Verwendung von sudo ausgeführt werden muss, damit es nicht von der übergeordneten Shell mithilfe von source aufgerufen werden kann.

Es sollte möglich sein, da Paketmanager wie apt es tun. Gibt es eine robuste Möglichkeit, meinen Ansatz zu verbessern? Wie wird das normalerweise gemacht, und gibt es eine gute Anleitung zum Schreiben von Bash-Installern?

+0

"* Paketmanager wie apt tun es. *" - Ich glaube nicht, dass das wahr ist. Haben Sie Beweise, die diese Behauptung stützen? –

+0

Wenn Sie sich an nichts anderes mehr über Shell-Programmierung erinnern, denken Sie daran, * ein Skript kann die Umgebung seiner Eltern nicht ändern *.Dies ist nur eine andere Möglichkeit, auszudrücken, dass eine * Untershell die Umgebung ihrer Eltern nicht ändern kann *. Ich glaube, das ist ein Fall, in dem "Nein, wirklich bedeutet ... Nein" –

+0

@Rob Ich meine nicht, Paket-Manager tun alles andere als mein ultimatives Ziel hier zu erreichen, um den Befehl sofort nach der Installation zugänglich zu machen. – Ixxie

Antwort

3

Sie können nicht. Weder kann apt.

Ein Paketmanager schreibt stattdessen einfach die erforderlichen Daten/Variablen in eine Datei, die entweder vom Programm selbst, von einem Patch für das Programm oder von einem Wrapper gelesen werden.

Gute Beispiele finden Sie in /etc/default/*. Dies sind Dateien mit variabler Definitionen, und einige sogar helfend beschreiben, woher sie stammen sind:

$ cat /etc/default/ssh 
# Default settings for openssh-server. This file is sourced by /bin/sh from 
# /etc/init.d/ssh. 

# Options to pass to sshd 
SSHD_OPTS= 

Sie werden feststellen, dass keine der Optionen in der aktuellen Shell eingestellt sind nach der Installation eines Pakets, da Programme, um sie zu bekommen direkt aus den Dateien auf die eine oder andere Weise.

3

Die einzige Möglichkeit, die aktuelle Shell zu ändern, besteht darin, ein Skript zu erstellen. Das ist unvermeidlich, also fang dort an. Schreiben Sie ein Skript, das source d ist. Dieses Skript wird sein aktuelles Skript aufrufen.

Ihr aktuelles Skript muss mit dem Quellcode kommunizieren, um ihm mitzuteilen, was geändert werden soll. Ein gängiger Weg besteht darin, Variablenzuweisungen zu protokollieren, die vom Aufrufer direkt ausgeführt werden können. Zum Beispiel:

printf 'export SCRIPT_HOME=%q\n' "$SCRIPTPATH" 

Mit printf mit %q sorgt für Sonderzeichen werden richtig übersetzt werden.

Dann haben Sie das source d Skript eval das innere Skript.

eval "$(sudo install-script.sh)" 

Wenn Sie das source ing des Top-Skripts verbergen wollen, dass es hinter einer Alias ​​oder ein Shell-Funktion verbergen konnte.