ฉันอยู่ในสถานการณ์ที่น่าสนใจเล็กน้อยซึ่งฉันมีสคริปต์ Python ที่สามารถเรียกใช้โดยผู้ใช้หลายคนที่มีสภาพแวดล้อมหลากหลาย (และ PATH) และในระบบ Linux ที่หลากหลาย ฉันต้องการให้สคริปต์นี้สามารถใช้งานได้กับสิ่งเหล่านี้ให้มากที่สุดโดยไม่มีข้อ จำกัด นี่คือการตั้งค่าที่รู้จักบางส่วน:
- Python 2.6 เป็นรุ่น Python ของระบบดังนั้น python, python2 และ python2.6 มีอยู่ใน / usr / bin (และเทียบเท่า)
- Python 2.6 เป็นรุ่น Python ของระบบดังกล่าวข้างต้น แต่ Python 2.7 ได้รับการติดตั้งไว้ข้างๆเป็น python2.7
- Python 2.4 เป็นรุ่น Python ของระบบซึ่งสคริปต์ของฉันไม่รองรับ ใน / usr / bin เรามี python, python2 และ python2.4 ซึ่งเทียบเท่าและ python2.5 ซึ่งสคริปต์สนับสนุน
ฉันต้องการเรียกใช้สคริปต์หลามปฏิบัติการที่เหมือนกันในทั้งสามนี้ มันจะดีถ้าพยายามใช้ /usr/bin/python2.7 ก่อนถ้ามีอยู่ให้ถอยกลับไปที่ /usr/bin/python2.6 จากนั้นถอยกลับไปที่ /usr/bin/python2.5 จากนั้น ข้อผิดพลาดเพียงถ้าไม่มีสิ่งเหล่านี้อยู่ ฉันไม่ได้วางสายโดยใช้ 2.x ที่เป็นไปได้ล่าสุดตราบใดที่สามารถหาล่ามที่ถูกต้องได้หากมี
ความชอบครั้งแรกของฉันคือการเปลี่ยนแนว shebang จาก:
#!/usr/bin/python
ถึง
#!/usr/bin/python2.[5-7]
ตั้งแต่นี้ทำงานได้ดีในทุบตี แต่การเรียกใช้สคริปต์ให้:
/usr/bin/python2.[5-7]: bad interpreter: No such file or directory
โอเคดังนั้นฉันลองทำสิ่งต่อไปนี้ซึ่งใช้ได้ใน bash:
#!/bin/bash -c /usr/bin/python2.[5-7]
แต่สิ่งนี้ล้มเหลวด้วย:
/bin/bash: - : invalid option
ตกลงเห็นได้ชัดว่าฉันสามารถเขียนเชลล์สคริปต์แยกต่างหากที่พบล่ามที่ถูกต้องและรันสคริปต์ไพ ธ อนโดยใช้ล่ามอะไรก็ได้ที่พบ ฉันแค่พบว่ามันเป็นเรื่องยุ่งยากที่จะแจกจ่ายสองไฟล์โดยที่ไฟล์ควรจะพอเพียงตราบใดที่มันรันด้วยล่าม python 2 ที่ทันสมัยที่สุด การขอให้คนเรียกล่ามอย่างชัดเจน (เช่น$ python2.5 script.py
) ไม่ได้เป็นตัวเลือก การใช้ PATH ของผู้ใช้ในการตั้งค่าวิธีการบางอย่างนั้นก็ไม่ใช่ตัวเลือก
แก้ไข:
การตรวจสอบเวอร์ชันภายในสคริปต์ Python จะไม่ทำงานเนื่องจากฉันใช้คำสั่ง "with" ซึ่งมีอยู่ตั้งแต่ Python 2.6 (และสามารถใช้ใน 2.5 ด้วยfrom __future__ import with_statement
) สิ่งนี้ทำให้สคริปต์ล้มเหลวทันทีด้วย SyntaxError ที่ผู้ใช้ไม่เป็นมิตรและป้องกันไม่ให้ฉันมีโอกาสตรวจสอบเวอร์ชันก่อนและปล่อยข้อผิดพลาดที่เหมาะสม
ตัวอย่าง: (ลองใช้ตัวแปลภาษา Python น้อยกว่า 2.6)
#!/usr/bin/env python
import sys
print "You'll never see this!"
sys.exit()
with open('/dev/null', 'w') as out:
out.write('something')
./script.py
) จะทำให้ python2.4 เรียกใช้งานซึ่งจะทำให้โค้ดของคุณตรวจพบว่าเป็นเวอร์ชันที่ไม่ถูกต้อง (และออกจากสมมุติ) แต่มี python2.5 ที่ดีอย่างสมบูรณ์ที่สามารถใช้เป็นล่ามแทนได้!
exec
ไม่ถ้าใช่มิฉะนั้นจะพิมพ์ข้อผิดพลาด
execve
) ข้อโต้แย้งเป็นตัวอักษรสตริงไม่มี globbing ไม่มี regexps แค่นั้นแหละ. แม้ว่า arg แรกคือ "/ bin / bash" และตัวเลือกที่สอง ("-c ... ") ตัวเลือกเหล่านั้นจะไม่ถูกแยกวิเคราะห์โดยเชลล์ พวกมันจะถูกส่งไปยัง bash executable ซึ่งเป็นสาเหตุที่ทำให้คุณได้รับข้อผิดพลาดเหล่านั้น นอกจากนี้ shebang ยังทำงานได้ก็ต่อเมื่อเริ่มต้นเท่านั้น ดังนั้นคุณจะโชคดีที่นี่ฉันกลัว (สั้น ๆ ของสคริปต์ที่พบล่ามหลามและป้อนมันที่นี่หมอเอกสารซึ่งฟังดูเหมือนเป็นระเบียบอันยิ่งใหญ่)
import sys; sys.version_info()
เพื่อตรวจสอบว่าผู้ใช้มีเวอร์ชันหลามที่ต้องการหรือไม่