459 Stimmen

Wie lassen sich andere Skripte am besten einbinden?

Normalerweise würde man ein Skript mit "source" einbinden

z. B:

main.sh:

#!/bin/bash

source incl.sh

echo "The main script"

incl.sh:

echo "The included script"

Die Ausgabe der Ausführung von "./main.sh" ist:

The included script
The main script

... Wenn Sie nun versuchen, das Shell-Skript von einem anderen Ort aus auszuführen, kann es das Include nicht finden, es sei denn, es befindet sich in Ihrem Pfad.

Wie kann man sicherstellen, dass das Skript das Include-Skript findet, insbesondere wenn das Skript beispielsweise portabel sein muss?

272voto

Chris Boran Punkte 4653

Ich neige dazu, meine Skripte alle relativ zueinander zu gestalten. Auf diese Weise kann ich dirname verwenden:

#!/bin/sh

my_dir="$(dirname "$0")"

"$my_dir/other_script.sh"

244voto

sacii Punkte 2139

Ich weiß, ich bin zu spät dran, aber das sollte unabhängig davon funktionieren, wie Sie das Skript starten und ausschließlich Builtins verwenden:

DIR="${BASH_SOURCE%/*}"
if [[ ! -d "$DIR" ]]; then DIR="$PWD"; fi
. "$DIR/incl.sh"
. "$DIR/main.sh"

. (Punkt) ist ein Alias für den Befehl source , $PWD ist der Pfad für das Arbeitsverzeichnis, BASH_SOURCE ist eine Array-Variable, deren Mitglieder die Namen der Quelldateien sind, ${string%substring} entfernt die kürzeste Übereinstimmung von $substring von der Rückseite von $string

59voto

tardate Punkte 15638

Eine Alternative zu:

scriptPath=$(dirname $0)

ist:

scriptPath=${0%/*}

der Vorteil ist, dass man nicht von dirname abhängig ist, das kein eingebauter Befehl ist (und in Emulatoren nicht immer verfügbar)

54voto

dsm Punkte 10073

Wenn sie sich im selben Verzeichnis befindet, können Sie dirname $0 :

#!/bin/bash

source $(dirname $0)/incl.sh

echo "The main script"

32voto

Mat131 Punkte 447

Ich denke, der beste Weg, dies zu tun, ist der Weg von Chris Boran, ABER Sie sollten MY_DIR auf diese Weise berechnen:

#!/bin/sh
MY_DIR=$(dirname $(readlink -f $0))
$MY_DIR/other_script.sh

Um die Man Pages für readlink zu zitieren:

readlink - display value of a symbolic link

...

  -f, --canonicalize
        canonicalize  by following every symlink in every component of the given 
        name recursively; all but the last component must exist

Mir ist noch nie ein Anwendungsfall begegnet, bei dem MY_DIR nicht korrekt berechnet wird. Wenn Sie auf Ihr Skript über einen Symlink in Ihrem $PATH es funktioniert.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X