ฉันมีสคริปต์ Python ที่ต้องรันด้วยการติดตั้ง python มีวิธีในการสร้าง shebang ให้มันทำงานด้วย$FOO/bar/MyCustomPythonหรือไม่?
ฉันมีสคริปต์ Python ที่ต้องรันด้วยการติดตั้ง python มีวิธีในการสร้าง shebang ให้มันทำงานด้วย$FOO/bar/MyCustomPythonหรือไม่?
คำตอบ:
สาย shebang มี จำกัด มาก ภายใต้ตัวแปร unix จำนวนมาก (รวมถึง Linux) คุณสามารถมีได้สองคำเท่านั้น: คำสั่งและอาร์กิวเมนต์เดียว นอกจากนี้ยังมักจะมีข้อจำกัดความยาว
วิธีแก้ปัญหาทั่วไปคือการเขียนเปลือกห่อเล็ก ๆ ชื่อสคริปต์ Python foo.pyและวางสคริปต์เปลือกติดกับและเรียกมันว่าfoo.py fooวิธีนี้ไม่จำเป็นต้องมีส่วนหัวใด ๆ ในสคริปต์ Python
#!/bin/sh
exec "$FOO/bar/MyCustomPython" "$0.py" "$@"
อีกวิธีหนึ่งที่น่าดึงดูดคือการเขียนสคริปต์ตัวห่อหุ้มแบบเดียวกับที่กล่าวไว้ข้างต้นและวางไว้#!/path/to/wrapper/scriptในแนวชีทบนสคริปต์ Python อย่างไรก็ตามยูนิเซฟส่วนใหญ่ไม่รองรับการผูกมัดของสคริปต์ shebang ดังนั้นสิ่งนี้จะไม่ทำงาน
หากMyCustomPythonอยู่ใน$PATHนั้นคุณสามารถใช้envเพื่อค้นหา:
#!/usr/bin/env MyCustomPython
import …
อีกวิธีหนึ่งคือการจัดเรียงสคริปต์ให้เป็นทั้งเชลล์สคริปต์ที่ถูกต้อง (ซึ่งโหลด Python ล่ามที่ถูกต้องด้วยตัวเอง) และสคริปต์ที่ถูกต้องในภาษาเป้าหมาย (นี่คือ Python) สิ่งนี้ต้องการให้คุณหาวิธีเขียนสคริปต์สองภาษาดังกล่าวสำหรับภาษาเป้าหมายของคุณ ใน Perl if $running_under_some_shellนี้เป็นที่รู้จักกัน
#!/bin/sh
eval 'exec "$FOO/bar/MyCustomPerl" -wS $0 ${1+"$@"}'
if $running_under_some_shell;
use …
ต่อไปนี้เป็นวิธีหนึ่งในการสร้างเอฟเฟกต์เดียวกันใน Python ในเชลล์"true"คือtrueยูทิลิตีซึ่งจะละเว้นอาร์กิวเมนต์ (สองสตริงอักขระเดี่ยว:และ') และส่งคืนค่าจริง ใน Python "true"เป็นสตริงที่เป็นจริงเมื่อตีความว่าเป็นบูลีนดังนั้นนี่คือifคำสั่งที่เป็นจริงเสมอและดำเนินการตามตัวอักษรสตริง
#!/bin/sh
if "true" : '''\'
then
exec "$FOO/bar/MyCustomPython" "$0" "$@"
exit 127
fi
'''
import …
PYTHONPATHตัวแปร env เพื่อโหลดโมดูลจากตำแหน่งที่ไม่ได้มาตรฐานสำหรับสคริปต์ CGI บนระบบที่ฉันไม่สามารถเข้าถึงรูตได้ ช่วยชีวิต ขอบคุณอีกครั้ง.
เส้น Shebang ไม่ผ่านการขยายตัวของตัวแปรดังนั้นคุณจึงไม่สามารถใช้งานได้$FOO/MyCustomPythonเพราะมันจะค้นหาไฟล์ปฏิบัติการที่เรียกว่า dollar-FOO -...
อีกทางเลือกหนึ่งคือให้ shebang ของคุณชี้ไปที่เชลล์สคริปต์ในฐานะล่ามและเชลล์สคริปต์นี้สามารถใช้ตัวแปรสภาพแวดล้อมเพื่อค้นหาที่ถูกต้องและดำเนินการได้
ตัวอย่าง: สร้างmypython.shสคริปต์ใน/usr/local/bin(หรือไดเรกทอรีอื่น ๆ ของคุณ$PATH) ด้วยเนื้อหาดังต่อไปนี้:
#! /bin/sh
PYTHON="$FOO/bar/MyCustomPython"
exec "$PYTHON" "$@"
จากนั้นคุณสามารถใช้บรรทัด shebang นี้เพื่อให้สคริปต์ Python ดำเนินการผ่านMyCustomPythonทางmypython.sh:
#!/usr/bin/env mypython.sh
$pythonไม่ใช่$PYTHONตามแบบแผนเราใช้ประโยชน์จากตัวแปรสภาพแวดล้อม (PAGER, EDITOR, SHELL ... $PYTHONในสคริปต์ของคุณไม่ใช่ตัวแปรสภาพแวดล้อม) และตัวแปรเชลล์ภายใน (BASH_VERSION, RANDOM, ... ) ชื่อตัวแปรอื่น ๆ ทั้งหมดควรมีตัวอักษรพิมพ์เล็กอย่างน้อยหนึ่งตัว อนุสัญญานี้หลีกเลี่ยงการแก้ไขตัวแปรสภาพแวดล้อมและภายในโดยไม่ตั้งใจ นอกจากนี้อย่าใช้ส่วนขยายสำหรับสคริปต์ของคุณ สคริปต์กำหนดคำสั่งใหม่ที่คุณสามารถเรียกใช้ได้และโดยทั่วไปคำสั่งจะไม่ได้รับส่วนขยาย
คุณสามารถใช้พา ธ สัมบูรณ์ไปยังการติดตั้งหลามแบบกำหนดเองหรือคุณสามารถใส่มันลงใน$PATHและใช้งาน#!/usr/bin/env [command]ได้ มิฉะนั้นให้เขียน wrapper สำหรับมันและใช้execเพื่อแทนที่อิมเมจกระบวนการดังตัวอย่าง:
#!/bin/bash
exec "$ENV/python" "$@"
ขั้นแรกให้พิจารณาว่ารุ่น Python ของคุณแตกต่างจาก Python มาตรฐานที่ติดตั้งไว้แล้วอย่างไร (ตัวอย่างเช่นโมดูลเพิ่มเติม) จากนั้นเมื่อเริ่มต้นโปรแกรม 'switch' วิธีที่ Python เรียกว่า:
#!/usr/bin/python
import os
import sys
try:
import MyCustomModule
except ImportError:
# only need to use expandvar if you know the string below has an envvar
custprog = os.path.expandvar("$FOO/bar/MyCustomPython")
os.execv(custprog, sys.argv) # call alternate python with the same arguments
raise SystemExit('could not call %s' % custprog)
# if we get here, then we have the correct python interpreter
สิ่งนี้จะทำให้โปรแกรมสามารถเรียกใช้งานได้โดยอินสแตนซ์อื่นของ Python ฉันทำสิ่งที่คล้ายกันสำหรับอินสแตนซ์ที่มีไลบรารี sql ในตัวที่ไม่สามารถนำเข้าเป็นโมดูลในหลามของระบบ
หากคุณสามารถแทนที่$FOOใน$FOO/bar/MyCustomPythonที่มีตัวเลือกเส้นทางคอนกรีตคุณสามารถบอกenvบรรทัด shebang ที่จะมองขึ้นรุ่นหลามของคุณกำหนดเองโดยการตั้งค่าได้โดยตรงที่กำหนดเองPATHในนั้น
#!/usr/bin/env PATH="/path1/to/MyCustomPython:/path2/to/MyCustomPython" python
แก้ไข : ดูเหมือนว่าจะทำงานโดยไม่มีเครื่องหมายคำพูดล้อมรอบการกำหนดค่า PATH:
#!/usr/bin/env PATH=/path1/to/MyCustomPython:/path2/to/MyCustomPython python
PATHเช่นนี้:PATH=$PATH:/path/to/whatever...