2012-07-03 16 views
8

Tôi có vấn đề này:

System A chạy Ubuntu và cần Python 2.6 cho một loạt các thứ khác nhau.
Tôi đã cài đặt riêng Python 2.7 trên System A
System BPython 2.7 nguyên bản.
Đối phó với nhiều phiên bản python khi file python phải sử dụng #/bin/env python

Tôi có một tập lệnh python BLAH có nội dung là #!/bin/env python ở trên cùng.
Tiếp tục thực hiện một tập lệnh khác SIGH, lên trên cùng cũng cho biết: #!/bin/env python.

BLAH cần chạy trên một trong hai System A hoặc System B, và nó luôn luôn cần chạy Python 2.7

----
Một phần của giải pháp của tôi cho đến nay:
Có một kịch bản wrapper rằng đầu tiên cố gắng để xem nếu which python trỏ đến Python 2.7
Nếu không sao thì hãy chạy BLAH với đường dẫn đó cho python.
Khác thử which python2.7 và sử dụng đường dẫn đó để chạy BLAH và thêm đường dẫn đó vào env PATH.

Vấn đề với giải pháp này là:

On System A (mà đã Python 2.7 được cài đặt riêng)
Khi BLAH thực thi, nó chạy với Python 2.7 vì kịch bản wrapper tôi đã viết (okay cho đến nay ..)
Khi BLAH spawns SIGH, SIGH sử dụng công việc để tìm trăn trong đường dẫn và sau đó nó gặp rắc rối vì nó đang tìm kiếm python trong env 's PATH và nó phải được tìm kiếm python2.7 trong đường dẫn.

Có cách nào xử lý vấn đề này một cách rõ ràng không?

Cảm ơn trước!

+0

Bạn có thể nhập, sau đó chạy SIGH từ BLAH không? –

+0

Tôi không chắc chắn bạn cần phải thêm đường dẫn mà bạn có được từ 'đó' để' PATH' - 'mà' thực sự sẽ chỉ tìm kiếm đường dẫn chứa trong' PATH'. – jedwards

Trả lời

9

Nếu bạn có một kịch bản mà cần một phiên bản python nào đó, ví dụ 2.7, tôi muốn thay đổi dòng đầu tiên để

#!/bin/env python2.7 

Và sau đó đảm bảo rằng python2.7 là trên con đường của bạn (bạn có thể phải thêm symlink thích hợp). Trong tất cả các bản phân phối tôi đã sử dụng, các liên kết này đã tồn tại.

(Trong thực tế, python thường là một liên kết tượng trưng đến pythonX mà là một liên kết tượng trưng đến pythonX.Y hoặc, trong trường hợp của tôi, python -> python2 -> python2.7.)

Không cần để mã hóa cứng một đường dẫn đầy đủ, vì điều này có thể thay đổi từ distro để distro hoặc hộp để hộp.

Nhưng vì không có sự mơ hồ đối với tệp thực thi trên đường dẫn của bạn có tên là python2.7, bạn sẽ ổn mà không phải lo lắng về đường dẫn mã hóa cứng.

Ngoài ra, từ bên trong kịch bản đầu tiên, bạn có thể gọi người phiên dịch python trực tiếp, như trong:

subprocess.Popen(['pythonX.Y', SCRIPT_NAME]) 

thay vì

subprocess.Popen([SCRIPT_NAME]) 

EDIT Như JF Sebastian lưu ý trong các ý kiến, bạn có thể sử dụng sys.executable trong đối số đầu tiên để đảm bảo rằng tập lệnh thứ hai được chuyển cho cùng một trình thông dịch như là phiên bản đầu tiên. ví dụ

subprocess.Popen([sys.executable, SCRIPT_NAME]) 

Là một mặt lưu ý, có thể có hoặc có thể không hữu ích, bạn có thể truy cập vào phiên bản của "hiện tại" thông dịch Python bên kịch bản bởi

import sys 
print(sys.hexversion) 

mà có thể hữu ích để xác định liệu trình thông dịch chính xác có đang chạy hay không.

+0

@jedwards một số shebang không hoạt động, nhận lỗi đường dẫn không hợp lệ trong apache – Volatil3

3

Điều tôi sẽ làm là thay đổi trực tiếp số #!/bin/env thành đường dẫn python2.7 trực tiếp, ví dụ: #!/usr/local/bin/python2.7 sẽ hoạt động.

Trong trường hợp hệ thống A và đường python2.7 B là ở những nơi khác nhau (trong đó có vẻ là trường hợp của bạn), bạn luôn có thể tạo liên kết tượng trưng như thế này:

ln -s /bin/python2.7 /usr/local/bin/python2.7 

và nó sẽ chỉ làm việc tốt.

2

Tại sao không sử dụng virtualenv? Nó cho phép bạn sử dụng bất kỳ phiên bản python cài đặt (ngoài những thứ khác) ...

starenka /tmp % virtualenv test -ppython2.6 
Running virtualenv with interpreter /usr/bin/python2.6 
New python executable in test/bin/python2.6 
Also creating executable in test/bin/python 
Installing setuptools............................done. 
Installing pip...............done. 

starenka /tmp % source test/bin/activate 

(test)starenka /tmp % which python 
/tmp/test/bin/python 

(test)starenka /tmp % python --version 
Python 2.6.8 

(test)starenka /tmp % echo '#!/usr/bin/env python\nimport sys; print sys.version_info' > test/test.py 

(test)starenka /tmp % chmod +x test/test.py 

(test)starenka /tmp % test/test.py 
(2, 6, 8, 'final', 0) 

starenka /tmp % virtualenv test7 -ppython2.7 
Running virtualenv with interpreter /usr/bin/python2.7 
New python executable in test7/bin/python2.7 
Also creating executable in test7/bin/python 
Installing setuptools............done. 
Installing pip...............done. 
starenka /tmp % source test7/bin/activate 

(test7)starenka /tmp % which python 
/tmp/test7/bin/python 

(test7)starenka /tmp % python --version 
Python 2.7.3rc2 

(test7)starenka /tmp % echo '#!/usr/bin/env python\nimport sys; print sys.version_info' > test7/test.py 

(test7)starenka /tmp % chmod +x test7/test.py 

(test7)starenka /tmp % test7/test.py 
sys.version_info(major=2, minor=7, micro=3, releaselevel='candidate', serial=2) 
0

ngốc và đơn giản

Trong vỏ, nếu cần thiết:

ln -s /path/to/your/python2.X /usr/local/bin/python2 

Trong Python tập lệnh:

#!/bin/bash 
"exec" "python2" "$0" 

Tôi đã trải qua loại chuyên nghiệp này blems, và giải pháp này đã giải quyết hầu hết các trường hợp và dễ dàng di chuyển từ một hệ thống này sang hệ thống khác (bạn có thể gặp các đường dẫn khác nhau giữa các hệ thống, các phiên bản khác nhau của phần mềm ...). Đầu tiên tạo một liên kết tượng trưng để đảm bảo rằng bạn sẽ chạy đúng phiên bản Python (điều này đặc biệt đúng lúc bây giờ bạn không bao giờ biết nếu Python3 chỉ là Python), và sau đó dựa vào bash env. Vì vậy, bạn không thay đổi kịch bản của bạn mỗi khi bạn nhắm mục tiêu một hệ thống cho một util-script mà không gọi cho những rắc rối của một gói.