ฉันมีสคริปต์ 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...