Bei Verwendung von source in einem Bash-Skript wird der Fehler "source: not found" angezeigt

159

Ich versuche (wie ich dachte) ein einfaches Bash-Skript zu schreiben, das:

  1. Führen Sie virtualenv aus, um eine neue Umgebung für 1 US-Dollar zu erstellen
  2. Aktivieren Sie die virtuelle Umgebung
  3. Mach noch ein paar Sachen (installiere django, füge django-admin.py zum Pfad des virtualenv hinzu usw.)

Schritt 1 funktioniert ganz gut, aber ich kann die virtuelle Umgebung scheinbar nicht aktivieren. Für diejenigen, die mit virtualenv nicht vertraut sind, wird eine activateDatei erstellt, die die virtuelle Umgebung aktiviert. Über die CLI führen Sie sie mit aussource

source $env_name/bin/activate

Dabei ist $ env_name offensichtlich der Name des Verzeichnisses, in dem die virtuelle Umgebung installiert ist.

In meinem Skript speichere ich nach dem Erstellen der virtuellen Umgebung den Pfad zum Aktivierungsskript wie folgt:

activate="`pwd`/$ENV_NAME/bin/activate"

Aber wenn ich anrufe source "$activate", bekomme ich folgendes:

/home/clawlor/bin/scripts/djangoenv: 20: source: not found

Ich weiß, dass dies $activateden richtigen Pfad zum Aktivierungsskript enthält. Tatsächlich teste ich sogar, dass eine Datei vorhanden ist, bevor ich aufrufe source. Aber sourceselbst scheint es nicht zu finden. Ich habe auch versucht, alle Schritte manuell in der CLI auszuführen, wo alles gut funktioniert.

Bei meinen Recherchen habe ich dieses Skript gefunden , das dem ähnelt, was ich möchte, aber auch viele andere Dinge tut, die ich nicht benötige, wie das Speichern aller virtuellen Umgebungen in einem ~ / .virtualenv-Verzeichnis (oder was auch immer sich darin befindet) $ WORKON_HOME). Aber es scheint mir, dass er den Weg dorthin schafft activateund source "$activate"im Grunde genauso anruft, wie ich es bin.

Hier ist das Skript in seiner Gesamtheit:

#!/bin/sh

PYTHON_PATH=~/bin/python-2.6.1/bin/python

if [ $# = 1 ]
then
    ENV_NAME="$1"
    virtualenv -p $PYTHON_PATH --no-site-packages $ENV_NAME
    activate="`pwd`/$ENV_NAME/bin/activate"

    if [ ! -f "$activate" ]
    then
        echo "ERROR: activate not found at $activate"
        return 1
    fi

    source "$activate"
else
    echo 'Usage: djangoenv ENV_NAME'
fi

HAFTUNGSAUSSCHLUSS: Mein Bash Script-Fu ist ziemlich schwach. Ich fühle mich in der CLI ziemlich wohl, aber es kann durchaus einen extrem dummen Grund geben, warum dies nicht funktioniert.

Chris Lawlor
quelle

Antworten:

230

Wenn Sie ein Bash-Skript schreiben, nennen Sie es beim Namen:

#!/bin/bash

/ bin / sh ist garantiert keine Bash. Dies verursachte vor einigen Jahren eine Menge defekter Skripte in Ubuntu (IIRC).

Die eingebaute Quelle funktioniert in Bash einwandfrei. Sie können aber auch einfach einen Punkt verwenden, wie von Norman vorgeschlagen.

Waffen
quelle
Diese Lösung war ursprünglich ein Kommentar in Norman Ramseys Antwort. Da dies das Problem tatsächlich behoben hat, habe ich dies als "akzeptierte Antwort" geändert
Chris Lawlor
184

In dem POSIX-Standard, der /bin/shrespektieren soll, ist der Befehl .(ein einzelner Punkt) nicht source. Der sourceBefehl ist ein csh-ismus, in den hineingezogen wurde bash.

Versuchen

. $env_name/bin/activate

Oder wenn Sie Nicht-POSIX- bashOrganismen in Ihrem Code haben müssen, verwenden Sie #!/bin/bash.

Norman Ramsey
quelle
1
Das behebt es. (Ändern von / bin / sh in / bin / bash). Aus irgendeinem Grund wird die Umgebung in der CLI nicht aktiviert, wenn das Skript beendet ist, aber das ist ein kleines Problem.
Chris Lawlor
8
Laut Bash source ist das Handbuch ein Synonym für ..
Richard Hansen
1
Ich bin darauf gestoßen, als ich einen Docker-Container mit einem solchen Einstiegspunkt verwendet habe /bin/sh -c '/path/to/script.sh'. Obwohl mein Skript ein Bash-Skript war, konnte die Quelle die Exporte nicht beschaffen. Aber "." hat funktioniert!
Nikhil Owalekar
30

Wenn Sie in Ubuntu das Skript mit ausführen sh scriptname.sh, tritt dieses Problem auf.

Versuchen Sie ./scriptname.shstattdessen , das Skript mit auszuführen .

Madhu
quelle
Ich habe dabei einen Segmentierungsfehler.
Max Pleaner
1
Datei muss ausführbar sein:chmod +x filename.sh
Randy
2
Irgendeine Idee warum das so ist?
Yuval Adam