Obtenir une erreur 'source: not found' lors de l'utilisation de la source dans un script bash

159

J'essaie d'écrire (ce que je pensais être) un simple script bash qui:

  1. exécutez virtualenv pour créer un nouvel environnement à 1 $
  2. activer l'environnement virtuel
  3. faire encore plus de choses (installer django, ajouter django-admin.py au chemin de virtualenv, etc.)

L'étape 1 fonctionne assez bien, mais je n'arrive pas à activer virtualenv. Pour ceux qui ne sont pas familiers avec virtualenv, il crée un activatefichier qui active l'environnement virtuel. À partir de la CLI, vous l'exécutez en utilisantsource

source $env_name/bin/activate

Où $ env_name, évidemment, est le nom du répertoire dans lequel l'environnement virtuel est installé.

Dans mon script, après avoir créé l'environnement virtuel, je stocke le chemin vers le script d'activation comme ceci:

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

Mais quand j'appelle source "$activate", j'obtiens ceci:

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

Je sais que $activatecontient le chemin correct vers le script d'activation, en fait je teste même qu'un fichier est là avant d'appeler source. Mais sourcelui-même ne semble pas pouvoir le trouver. J'ai également essayé d'exécuter toutes les étapes manuellement dans la CLI, où tout fonctionne bien.

Dans mes recherches, j'ai trouvé ce script , qui est similaire à ce que je veux mais qui fait aussi beaucoup d'autres choses dont je n'ai pas besoin, comme stocker tous les environnements virtuels dans un répertoire ~ / .virtualenv (ou tout ce qui se trouve dans $ WORKON_HOME). Mais il me semble qu'il crée le chemin vers activateet appelle source "$activate"essentiellement de la même manière que moi.

Voici le script dans son intégralité:

#!/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

AVIS DE NON-RESPONSABILITÉ: Mon script-fu bash est assez faible. Je suis assez à l'aise avec la CLI, mais il peut bien y avoir une raison extrêmement stupide que cela ne fonctionne pas.

Chris Lawlor
la source

Réponses:

230

Si vous écrivez un script bash, appelez-le par son nom:

#!/bin/bash

/ bin / sh n'est pas garanti d'être bash. Cela a provoqué une tonne de scripts cassés dans Ubuntu il y a quelques années (IIRC).

La source intégrée fonctionne très bien dans bash; mais vous pouvez tout aussi bien utiliser dot comme l'a suggéré Norman.

armes à feu
la source
Cette solution était à l'origine un commentaire dans la réponse de Norman Ramsey. Puisque c'est ce qui a réellement résolu le problème, j'ai changé cela pour être la `` réponse acceptée ''
Chris Lawlor
186

Dans le standard POSIX, qui /bin/shest censé respecter, la commande est .(un seul point), non source. La sourcecommande est un csh-ism qui a été intégré bash.

Essayer

. $env_name/bin/activate

Ou si vous devez avoir des bash-ismes non-POSIX dans votre code, utilisez #!/bin/bash.

Norman Ramsey
la source
1
Cela résout le problème. (en remplaçant / bin / sh par / bin / bash). Pour une raison quelconque, l'environnement n'est pas activé dans la CLI lorsque le script se termine, mais c'est un problème mineur.
Chris Lawlor
8
Selon le manuel Bash, il source est synonyme de ..
Richard Hansen du
1
Je suis tombé sur ce lors de l' utilisation d' un conteneur docker avec entrypoint comme ça, /bin/sh -c '/path/to/script.sh'. Même si mon script était un script bash, la source n'a pas réussi à générer les exportations. Mais "." travaillé!
Nikhil Owalekar le
31

Dans Ubuntu, si vous exécutez le script avec, sh scriptname.shvous rencontrez ce problème.

Essayez ./scriptname.shplutôt d' exécuter le script avec .

Madhu
la source
J'ai eu un défaut de segmentation en faisant cela.
max pleaner
1
Le fichier doit être exécutable:chmod +x filename.sh
Randy
2
Une idée pourquoi c'est?
Yuval Adam le
La seule chose qui a fonctionné pour mon Ubuntu
20.04