Mendapatkan kesalahan 'sumber: tidak ditemukan' saat menggunakan sumber dalam skrip bash

159

Saya mencoba menulis (apa yang saya pikir akan menjadi) skrip bash sederhana yang akan:

  1. jalankan virtualenv untuk membuat lingkungan baru dengan $ 1
  2. aktifkan lingkungan virtual
  3. lakukan beberapa hal lagi (instal django, tambahkan django-admin.py ke jalur virtualenv, dll.)

Langkah 1 bekerja dengan sangat baik, tapi sepertinya saya tidak bisa mengaktifkan virtualenv. Bagi mereka yang tidak terbiasa dengan virtualenv, itu menciptakan activatefile yang mengaktifkan lingkungan virtual. Dari CLI, Anda menjalankannya menggunakansource

source $env_name/bin/activate

Di mana $ env_name, jelas, adalah nama dir yang menginstal virtual env.

Di skrip saya, setelah membuat lingkungan virtual, saya menyimpan path ke skrip aktifkan seperti ini:

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

Tetapi ketika saya menelepon source "$activate", saya mendapatkan ini:

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

Saya tahu itu $activateberisi jalur yang benar untuk mengaktifkan skrip, bahkan saya bahkan menguji apakah ada file sebelum saya panggil source. Tapi sourceitu sendiri sepertinya tidak dapat menemukannya. Saya juga mencoba menjalankan semua langkah secara manual di CLI, di mana semuanya berfungsi dengan baik.

Dalam penelitian saya, saya menemukan skrip ini , yang mirip dengan apa yang saya inginkan tetapi juga melakukan banyak hal lain yang tidak saya butuhkan, seperti menyimpan semua lingkungan virtual dalam direktori ~ / .virtualenv (atau apa pun yang ada di dalam $ WORKON_HOME). Tapi menurut saya dia menciptakan jalan menuju activate, dan memanggil source "$activate"saya dengan cara yang sama.

Ini adalah keseluruhan skripnya:

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

PENOLAKAN: Script bash-fu saya cukup lemah. Saya cukup nyaman di CLI, tetapi mungkin ada beberapa alasan yang sangat bodoh karena ini tidak berfungsi.

Chris Lawlor
sumber

Jawaban:

230

Jika Anda menulis skrip bash, panggil dengan nama:

#!/bin/bash

/ bin / sh tidak dijamin sebagai bash. Ini menyebabkan banyak skrip yang rusak di Ubuntu beberapa tahun yang lalu (IIRC).

Sumber builtin bekerja dengan baik di bash; tetapi Anda mungkin juga hanya menggunakan titik seperti yang disarankan Norman.

senjata
sumber
Solusi ini awalnya adalah komentar dalam jawaban Norman Ramsey. Karena inilah yang sebenarnya memperbaiki masalah, saya telah mengubah ini menjadi 'jawaban yang diterima'
Chris Lawlor
185

Dalam standar POSIX, yang /bin/shseharusnya dihormati, perintahnya adalah .(satu titik), bukan source. The sourceperintah adalah csh-ism yang telah ditarik ke bash.

Mencoba

. $env_name/bin/activate

Atau jika Anda harus memiliki bash-isme non-POSIX dalam kode Anda, gunakan #!/bin/bash.

Norman Ramsey
sumber
1
Itu memperbaikinya. (mengubah / bin / sh ke / bin / bash). Untuk beberapa alasan lingkungan tidak diaktifkan di CLI ketika skrip selesai, tapi itu masalah kecil.
Chris Lawlor
8
Menurut manual Bash source adalah sinonim untuk ..
Richard Hansen
1
Saya menemukan ini ketika menggunakan wadah buruh pelabuhan dengan titik masuk seperti ini /bin/sh -c '/path/to/script.sh',. Meskipun skrip saya adalah skrip bash, sumber gagal mendapatkan sumber ekspor. Tapi "." bekerja!
Nikhil Owalekar
31

Di Ubuntu jika Anda menjalankan skrip dengan sh scriptname.shAnda mendapatkan masalah ini.

Coba jalankan skrip dengan ./scriptname.shgantinya.

Madhu
sumber
saya mendapat kesalahan segmentasi ketika melakukan ini.
maks pemohon
1
File harus dapat dieksekusi:chmod +x filename.sh
Randy
2
ada yang tahu ini kenapa?
Yuval Adam
Satu-satunya hal yang bekerja untuk Ubuntu 20,04 saya
Kirill_Zaitsev