it-swarm.com.de

Wie setze ich das aktuelle Arbeitsverzeichnis auf das Verzeichnis des Skripts?

Ich schreibe ein Bash-Skript. Ich brauche das aktuelle Arbeitsverzeichnis, um immer das Verzeichnis zu sein, in dem sich das Skript befindet.

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

465
jameshfisher
#!/bin/bash
cd "$(dirname "$0")"
545
ndim

Folgendes funktioniert auch:

cd "${0%/*}"

Die Syntax wird ausführlich in this StackOverflow answer beschrieben.

293
Paul Schulz

Probieren Sie die folgenden einfachen Einzeiler aus:


Für alle UNIX/OSX/Linux

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

Bash

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

Hinweis: In Befehlen wird ein doppelter Bindestrich (-) verwendet, um das Ende der Befehlsoptionen zu kennzeichnen, damit Dateien, die Bindestriche oder andere Sonderzeichen enthalten, den Befehl nicht unterbrechen.

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


Für Linux, Mac und andere * BSD:

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

Hinweis: realpath sollte standardmäßig in der gängigsten Linux-Distribution (wie Ubuntu) installiert sein, kann aber in einigen Fällen fehlen, sodass Sie sie installieren müssen.

Hinweis: Wenn Sie Bash verwenden, verwenden Sie ${BASH_SOURCE[0]} anstelle von $0. Andernfalls kann der Pfad bei der Beschaffung unterbrochen werden (source/.).

Andernfalls könnten Sie so etwas versuchen (es wird das erste vorhandene Tool verwenden):

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

Für Linux spezifisch:

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

Mit GNU readlink auf * BSD/Mac:

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

Hinweis: Sie müssen coreutils installiert haben (z. B. 1. Install Homebrew , 2. brew install coreutils).


In der Bash

In bash können Sie Parameter Expansions verwenden, um das zu erreichen, wie:

cd "${0%/*}"

es funktioniert jedoch nicht, wenn das Skript in demselben Verzeichnis ausgeführt wird.

Alternativ können Sie die folgende Funktion in bash definieren:

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

Diese Funktion benötigt 1 Argument. Wenn das Argument bereits einen absoluten Pfad hat, drucken Sie ihn so, wie er ist, andernfalls drucken Sie $PWD Variable + Dateinamenargument (ohne ./ Präfix).

oder hier ist die Version aus der Debian .bashrc -Datei:

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

Verbunden:

Siehe auch:

Wie kann ich das Verhalten von GNUs readlink -f auf einem Mac ermitteln?

160
kenorb
cd "$(dirname "${BASH_SOURCE[0]}")"

Es ist einfach. Es klappt.

63
Dan Moulding

Die akzeptierte Antwort eignet sich gut für Skripte, die nicht anderweitig verlinkt wurden, 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 in das ~/bin/ -Verzeichnis und nicht in das ~/project/ -Verzeichnis kopiert, wodurch Ihr Skript wahrscheinlich beschädigt wird, wenn der Zweck des cd darin besteht, Abhängigkeiten in Bezug auf ~/project/ einzuschließen.

Die symlink sichere Antwort ist unten:

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

readlink -f ist erforderlich, um den absoluten Pfad der möglicherweise verknüpften Datei aufzulösen.

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

5
James McGuigan

Dieses Skript scheint für mich zu funktionieren:

#!/bin/bash
mypath=`realpath $0`
cd `dirname $mypath`
pwd

Die pwd-Befehlszeile gibt den Speicherort des Skripts als aktuelles Arbeitsverzeichnis an, unabhängig davon, von wo aus ich es ausführe.

2
Amardeep AC9MF

Holen Sie sich den richtigen Pfad zu Ihrem Skript

if [ -L $0 ] ; then
    ME=$(readlink $0)
else
    ME=$0
fi
DIR=$(dirname $ME)

(Dies ist die Antwort auf meine Frage hier: Ermittelt den Namen des Verzeichnisses, in dem ein Skript ausgeführt wird )

1
rodnower
cd "`dirname $(readlink -f ${0})`"
1
user742030