825 Stimmen

Wie kann ich das aktuelle Arbeitsverzeichnis auf das Verzeichnis des Skripts in der Bash setzen?

Ich schreibe ein Bash-Skript. Das aktuelle Arbeitsverzeichnis muss immer das Verzeichnis sein, in dem sich das Skript befindet.

Das Standardverhalten ist, dass das aktuelle Arbeitsverzeichnis im Skript dasjenige der Shell ist, von der aus ich es ausführe, aber ich möchte dieses Verhalten nicht.

993voto

ndim Punkte 33229
#!/bin/bash
cd "$(dirname "$0")"

400voto

Paul Schulz Punkte 3689

Das Folgende funktioniert auch:

cd "${0%/*}"

Die Syntax ist ausführlich beschrieben in diese StackOverflow-Antwort.

256voto

kenorb Punkte 134883

Versuchen Sie es mit den folgenden einfachen Einzeilern:


Für alle UNIX/OSX/Linux

dir=$(cd -P -- "$(dirname -- "$0")" && pwd -P)

Bash

dir=$(cd -P -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)

Hinweis: Ein doppelter Bindestrich (--) wird in Befehlen verwendet, um das Ende von Befehlsoptionen zu kennzeichnen, so dass Dateien, die Bindestriche oder andere Sonderzeichen enthalten, den Befehl nicht unterbrechen.

Hinweis: Verwenden Sie in der Bash ${BASH_SOURCE[0]} zugunsten von $0 , sonst kann der Pfad beim Sourcen unterbrochen werden ( source / . ).


Für Linux, Mac und andere *BSD:

cd "$(dirname "$(realpath "$0")")";

Anmerkung: realpath sollte in den meisten gängigen Linux-Distributionen standardmäßig installiert sein (z. B. Ubuntu), aber in einigen kann es fehlen, so dass Sie es selbst installieren müssen.

Hinweis: Wenn Sie Bash verwenden, benutzen Sie ${BASH_SOURCE[0]} zugunsten von $0 , sonst kann der Pfad beim Sourcen unterbrochen werden ( source / . ).

Andernfalls können Sie so etwas versuchen (es wird das erste vorhandene Werkzeug verwendet):

cd "$(dirname "$(readlink -f "$0" || realpath "$0")")"

Für Linux spezifisch:

cd "$(dirname "$(readlink -f "$0")")"

Verwendung von GNU readlink auf *BSD/Mac:

cd "$(dirname "$(greadlink -f "$0")")"

Hinweis: Sie benötigen coreutils installiert (z.B. 1. installieren Selbstgebrautes , 2. brew install coreutils ).


In bash

In der Bash können Sie verwenden Parameter-Erweiterungen um das zu erreichen, wie:

cd "${0%/*}"

aber es funktioniert nicht, wenn das Skript aus demselben Verzeichnis ausgeführt wird.

Alternativ können Sie auch die folgende Funktion in der Bash definieren:

realpath () {
  [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"
}

Diese Funktion benötigt 1 Argument. Wenn das Argument bereits einen absoluten Pfad enthält, wird er so gedruckt, wie er ist, andernfalls wird $PWD Variable + Argument Dateiname (ohne ./ Präfix).

oder hier ist die Version aus Debian .bashrc Datei:

function realpath()
{
    f=$@
    if [ -d "$f" ]; then
        base=""
        dir="$f"
    else
        base="/$(basename "$f")"
        dir=$(dirname "$f")
    fi
    dir=$(cd "$dir" && /bin/pwd)
    echo "$dir$base"
}

Verwandt:

Siehe auch:

Wie kann ich das Verhalten von GNU's readlink -f auf einem Mac erhalten?

100voto

Dan Moulding Punkte 195982
cd "$(dirname "${BASH_SOURCE[0]}")"

Das ist ganz einfach. Es funktioniert.

23voto

James McGuigan Punkte 6675

Die akzeptierte Antwort funktioniert gut für Skripte, die nicht anderweitig symverlinkt wurden, wie z.B. in $PATH .

#!/bin/bash
cd "$(dirname "$0")"

Wenn das Skript jedoch über einen Symlink ausgeführt wird,

ln -sv ~/project/script.sh ~/bin/; 
~/bin/script.sh

Dies wird cd in die ~/bin/ Verzeichnis und nicht das ~/project/ Verzeichnis, was wahrscheinlich Ihr Skript zerstört, wenn der Zweck der cd ist die Einbeziehung von Abhängigkeiten relativ zu ~/project/

Die sichere Symlink-Antwort finden Sie unten:

#!/bin/bash
cd "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")"  # cd current directory

readlink -f ist erforderlich, um den absoluten Pfad der potenziell symverknüpften Datei aufzulösen.

Die Anführungszeichen sind erforderlich, um Dateipfade zu unterstützen, die möglicherweise Leerzeichen enthalten (schlechte Praxis, aber es ist nicht sicher, dass dies nicht der Fall sein wird)

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