Ottenere un errore "source: not found" quando si utilizza source in uno script bash


159

Sto cercando di scrivere (quello che pensavo sarebbe stato) un semplice script bash che:

  1. esegui virtualenv per creare un nuovo ambiente a $ 1
  2. attivare l'ambiente virtuale
  3. fare altro (installare django, aggiungere django-admin.py al percorso di virtualenv, ecc.)

Il passaggio 1 funziona abbastanza bene, ma non riesco ad attivare virtualenv. Per coloro che non hanno familiarità con virtualenv, crea un activatefile che attiva l'ambiente virtuale. Dalla CLI, la esegui usandosource

source $env_name/bin/activate

Dove $ env_name, ovviamente, è il nome della directory in cui è installato l'env virtuale.

Nel mio script, dopo aver creato l'ambiente virtuale, memorizzo il percorso dello script di attivazione in questo modo:

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

Ma quando chiamo source "$activate", ottengo questo:

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

So che $activatecontiene il percorso corretto per attivare lo script, infatti provo persino che un file è lì prima di chiamare source. Ma di per sourcesé non riesce a trovarlo. Ho anche provato a eseguire tutti i passaggi manualmente nella CLI, dove tutto funziona bene.

Nella mia ricerca ho trovato questo script , che è simile a quello che voglio ma sta facendo anche molte altre cose di cui non ho bisogno, come archiviare tutti gli ambienti virtuali in una directory ~ / .virtualenv (o qualunque cosa sia $ WORKON_HOME). Ma mi sembra che stia creando il percorso activatee che stia chiamando source "$activate"sostanzialmente nello stesso modo in cui sono io.

Ecco lo script nella sua interezza:

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

DISCLAIMER: Il mio script-fu bash è piuttosto debole. Sono abbastanza a mio agio con la CLI, ma potrebbe esserci qualche ragione estremamente stupida per cui questo non funziona.

Risposte:


230

Se stai scrivendo uno script bash, chiamalo per nome:

#!/bin/bash

/ bin / sh non è garantito per essere bash. Ciò ha causato un sacco di script rotti in Ubuntu alcuni anni fa (IIRC).

Il builtin sorgente funziona bene in bash; ma potresti anche usare il punto come suggerito da Norman.


Questa soluzione era originariamente un commento nella risposta di Norman Ramsey. Dal momento che questo è ciò che ha effettivamente risolto il problema, ho cambiato questa in "risposta accettata"
Chris Lawlor,

185

Nello standard POSIX, che /bin/shdovrebbe rispettare, il comando è .(un singolo punto), non source. Il sourcecomando è un csh-ismo che è stato tirato dentro bash.

Provare

. $env_name/bin/activate

Oppure, se devi avere un non-POSIX bashnel tuo codice, usa #!/bin/bash.


1
Questo lo risolve. (cambiando / bin / sh in / bin / bash). Per qualche ragione l'ambiente non è attivato nella CLI al termine dello script, ma questo è un problema minore.
Chris Lawlor,

8
Secondo il manuale di Bash source è sinonimo di ..
Richard Hansen,

1
Mi sono imbattuto in questo quando si utilizza un contenitore di finestra mobile con entrypoint come questo, /bin/sh -c '/path/to/script.sh'. Anche se la mia sceneggiatura era una bash, la fonte non è riuscita a procurarsi le esportazioni. Ma "." lavorato!
Nikhil Owalekar,

31

In Ubuntu se si esegue lo script con sh scriptname.shsi ottiene questo problema.

Prova invece a eseguire lo script con ./scriptname.sh.


ho riscontrato un errore di segmentazione durante questa operazione.
massimo Pleaner

1
Il file deve essere eseguibile:chmod +x filename.sh
Randy

2
Qualche idea sul perché questo sia?
Yuval Adam,

L'unica cosa che ha funzionato per il mio Ubuntu 20.04
Kirill_Zaitsev il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.