Obteniendo un error 'fuente: no encontrado' cuando se usa la fuente en un script bash

159

Estoy tratando de escribir (lo que pensé que sería) un script de bash simple que:

  1. ejecute virtualenv para crear un nuevo entorno a $ 1
  2. activar el entorno virtual
  3. hacer algunas cosas más (instalar django, agregar django-admin.py a la ruta del virtualenv, etc.)

El paso 1 funciona bastante bien, pero parece que no puedo activar virtualenv. Para aquellos que no están familiarizados con virtualenv, crea un activatearchivo que activa el entorno virtual. Desde la CLI, lo ejecutas usandosource

source $env_name/bin/activate

Donde $ env_name, obviamente, es el nombre del directorio en el que está instalado el env virtual.

En mi script, después de crear el entorno virtual, almaceno la ruta al script de activación de esta manera:

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

Pero cuando llamo source "$activate", me sale esto:

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

Sé que $activatecontiene la ruta correcta al script de activación, de hecho, incluso pruebo que hay un archivo antes de llamar source. Pero sourceparece que no puede encontrarlo. También he intentado ejecutar todos los pasos manualmente en la CLI, donde todo funciona bien.

En mi investigación encontré este script , que es similar a lo que quiero pero también está haciendo muchas otras cosas que no necesito, como almacenar todos los entornos virtuales en un directorio ~ / .virtualenv (o lo que sea que esté en $ WORKON_HOME). Pero me parece que él está creando el camino activatey llamando source "$activate"básicamente de la misma manera que yo.

Aquí está el guión en su totalidad:

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

DESCARGO DE RESPONSABILIDAD: Mi bash script-fu es bastante débil. Me siento bastante cómodo en la CLI, pero puede haber alguna razón extremadamente estúpida por la que esto no funciona.

Chris Lawlor
fuente

Respuestas:

230

Si está escribiendo un script bash, llámelo por su nombre:

#!/bin/bash

/ bin / sh no garantiza que sea bash. Esto causó una tonelada de scripts rotos en Ubuntu hace algunos años (IIRC).

La fuente incorporada funciona bien en bash; pero bien podrías usar el punto como lo sugirió Norman.

pistolas
fuente
Esta solución fue originalmente un comentario en la respuesta de Norman Ramsey. Dado que esto es lo que realmente solucionó el problema, he cambiado esto para que sea la 'respuesta aceptada'
Chris Lawlor
186

En el estándar POSIX, que /bin/shse supone debe respetar, el comando es .(un solo punto), no source. El sourcecomando es un csh-ismo en el que se ha introducido bash.

Tratar

. $env_name/bin/activate

O bien, si debe tener organismos que no sean POSIX bashen su código, use #!/bin/bash.

Norman Ramsey
fuente
1
Eso lo arregla. (cambiando / bin / sh a / bin / bash). Por alguna razón, el entorno no se activa en la CLI cuando finaliza el script, pero ese es un problema menor.
Chris Lawlor
8
Según el manual Bash source es sinónimo de ..
Richard Hansen
1
Me encontré con este cuando se utiliza un recipiente ventana acoplable con el punto de entrada de este tipo, /bin/sh -c '/path/to/script.sh'. Aunque mi script era un script bash, la fuente no pudo obtener las exportaciones. Pero "." ¡trabajó!
Nikhil Owalekar
31

En Ubuntu, si ejecutas el script sh scriptname.sh, obtienes este problema.

Intente ejecutar el script con en su ./scriptname.shlugar.

Madhu
fuente
Tengo un error de segmentación al hacer esto.
máximo demandante
1
El archivo debe ser ejecutable:chmod +x filename.sh
Randy
2
¿Alguna idea de por qué es esto?
Yuval Adam
Lo único que funcionó para mi Ubuntu 20.04
Kirill_Zaitsev