Gặp lỗi 'nguồn: không tìm thấy' khi sử dụng nguồn trong tập lệnh bash


159

Tôi đang cố gắng viết (những gì tôi nghĩ sẽ là) một tập lệnh bash đơn giản sẽ:

  1. chạy virtualenv để tạo môi trường mới với $ 1
  2. kích hoạt môi trường ảo
  3. làm thêm một số thứ (cài đặt django, thêm django-admin.py vào đường dẫn của virtualenv, v.v.)

Bước 1 hoạt động khá tốt, nhưng dường như tôi không thể kích hoạt virtualenv. Đối với những người không quen thuộc với virtualenv, nó tạo ra một activatetệp kích hoạt môi trường ảo. Từ CLI, bạn chạy nó bằngsource

source $env_name/bin/activate

Rõ ràng trong đó $ env_name là tên của thư mục mà env ảo được cài đặt.

Trong tập lệnh của tôi, sau khi tạo môi trường ảo, tôi lưu trữ đường dẫn đến tập lệnh kích hoạt như thế này:

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

Nhưng khi tôi gọi source "$activate", tôi nhận được điều này:

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

Tôi biết rằng $activatecó chứa đường dẫn chính xác đến tập lệnh kích hoạt, trên thực tế tôi thậm chí còn kiểm tra rằng một tập tin có ở đó trước khi tôi gọi source. Nhưng sourcechính nó dường như không thể tìm thấy nó. Tôi cũng đã thử chạy tất cả các bước theo cách thủ công trong CLI, nơi mọi thứ đều hoạt động tốt.

Trong nghiên cứu của tôi, tôi đã tìm thấy tập lệnh này , tương tự như những gì tôi muốn nhưng cũng đang làm rất nhiều thứ khác mà tôi không cần, như lưu trữ tất cả các môi trường ảo trong thư mục ~ / .virtualenv (hoặc bất cứ thứ gì có trong $ WORKON_HOME). Nhưng dường như với tôi rằng anh ta đang tạo ra con đường activatevà gọi source "$activate"về cơ bản giống như tôi.

Đây là toàn bộ kịch bản:

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

TUYÊN BỐ TỪ CHỐI: Bash script-fu của tôi khá yếu. Tôi khá thoải mái tại CLI, nhưng có thể có một số lý do cực kỳ ngu ngốc, điều này không hiệu quả.

Câu trả lời:


230

Nếu bạn đang viết một tập lệnh bash, hãy gọi nó bằng tên:

#!/bin/bash

/ bin / sh không được đảm bảo là bash. Điều này gây ra một tấn các tập lệnh bị hỏng trong Ubuntu vài năm trước (IIRC).

Nguồn dựng sẵn hoạt động tốt trong bash; nhưng bạn cũng có thể chỉ sử dụng dấu chấm như Norman đề xuất.


Giải pháp này ban đầu là một nhận xét trong câu trả lời của Norman Ramsey. Vì đây là điều thực sự đã khắc phục vấn đề, tôi đã thay đổi điều này thành 'câu trả lời được chấp nhận'
Chris Lawlor

185

Trong tiêu chuẩn POSIX, /bin/shđược cho là tôn trọng, lệnh là .(một dấu chấm đơn), không phải source. Các sourcelệnh là một csh-ism đã được kéo vào bash.

Thử

. $env_name/bin/activate

Hoặc nếu bạn phải có bashchủ nghĩa không phải POSIX trong mã của mình, hãy sử dụng #!/bin/bash.


1
Điều đó sửa chữa nó. (thay đổi / bin / sh thành / bin / bash). Vì một số lý do, môi trường không được kích hoạt trong CLI khi tập lệnh kết thúc, nhưng đó là một vấn đề nhỏ.
Chris Lawlor

8
Theo hướng dẫn Bash source là một từ đồng nghĩa cho ..
Richard Hansen

1
Tôi đã gặp điều này khi sử dụng một container docker với điểm vào như thế này /bin/sh -c '/path/to/script.sh'. Mặc dù tập lệnh của tôi là tập lệnh bash, nguồn không thành công trong việc xuất. Nhưng "." đã làm việc!
Nikhil Owalekar

31

Trong Ubuntu nếu bạn thực thi tập lệnh với sh scriptname.shbạn sẽ gặp vấn đề này.

./scriptname.shThay vào đó, hãy thử thực thi kịch bản .


tôi đã có một lỗi phân khúc khi làm điều này.
tối đa pleaner

1
Tệp phải được thực thi:chmod +x filename.sh
Randy

2
Có ai biết vì sao lại thế này không?
Yuval Adam

Điều duy nhất hoạt động cho Ubuntu
20.04
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.