/ usr / bin / env รู้ได้อย่างไรว่าจะใช้โปรแกรมใด


62

เมื่อฉันใช้ shebang #!/usr/bin/env pythonเพื่อเรียกใช้สคริปต์ระบบจะทราบได้อย่างไรว่าpythonควรใช้อย่างไร ถ้าฉันค้นหาpythonเส้นทางถังในตัวแปรสภาพแวดล้อมฉันไม่พบอะไรเลย

env | grep -i python

6
โอ้ฉันคิดว่าฉันคิดออกมันแค่ค้นหา $ PATH ของคุณสำหรับ 'python'
tMC

ฉันก็สงสัยเช่นกัน และทำไม / usr / bin / env ซึ่งตรงข้ามกับ / bin / env หรือ env หากเพียงรับรายการเส้นทางจาก env
Faheem Mitha

เพียงแค่ 'env' จะไม่ทำงานเพราะมันต้องเป็นเส้นทางที่เต็ม โปรแกรม 'env' มักจะพบใน / user / bin / env ใน distros บางแห่งอาจพบว่าเป็น / bin / env แต่จะปลอดภัยกว่าหากใช้กับ / usr / bin / env
rettops

คำตอบ:


54

shebang ต้องการเส้นทางแบบเต็มไปยังล่ามเพื่อใช้ดังนั้นไวยากรณ์ต่อไปนี้จะไม่ถูกต้อง:

#!python

การตั้งค่าเส้นทางแบบเต็มเช่นนี้อาจใช้งานได้:

#!/usr/local/bin/python

แต่จะไม่ใช่อุปกรณ์พกพาเนื่องจากอาจติดตั้งไพ/bin/opt/python/binอนหรือตำแหน่งอื่นใดก็ได้

การใช้ env

#!/usr/bin/env python

เป็นวิธีการที่ช่วยให้วิธีแบบพกพาเพื่อระบุระบบปฏิบัติการเส้นทางแบบเต็มเทียบเท่ากับหนึ่งที่ตั้งอยู่เป็นครั้งแรกในpythonPATH


56

shebangบรรทัด (จาก“ปังคม” คือ#!) การประมวลผลโดยเคอร์เนล PATHเคอร์เนลไม่ต้องการที่จะรู้เกี่ยวกับตัวแปรสภาพแวดล้อมเช่น ดังนั้นชื่อบนบรรทัด shebang ต้องเป็นพา ธ สัมบูรณ์ไปยังไฟล์ที่เรียกทำงานได้ คุณยังสามารถระบุอาร์กิวเมนต์เพิ่มเติมเพื่อส่งไปยังไฟล์เรียกใช้งานนั้นก่อนชื่อสคริปต์ (ด้วยข้อ จำกัด ที่ขึ้นกับระบบฉันจะไม่เข้าไปที่นี่) ตัวอย่างเช่นสำหรับสคริปต์ Python คุณสามารถระบุได้

#!/usr/bin/python

/usr/bin/python /path/to/scriptในบรรทัดแรกและเมื่อคุณรันสคริปต์เคอร์เนลจะดำเนินการในความเป็นจริง แต่นั่นไม่สะดวก: คุณต้องระบุเส้นทางแบบเต็มของคำสั่ง ถ้าคุณมีpythonใน/usr/binบางเครื่องและ/usr/local/binอื่น ๆ ? หรือคุณต้องการตั้งค่าของคุณPATHไป/home/joe/opt/python-2.5/binเพื่อที่จะใช้รุ่นที่เฉพาะเจาะจงของงูใหญ่? เนื่องจากเคอร์เนลจะไม่ทำการPATHค้นหาสำหรับคุณความคิดคือการทำให้เคอร์เนลรันคำสั่งที่จะค้นหาล่ามที่ต้องการในPATH:

#!/fixed/path/to/path-lookup-command python

ที่path-lookup-commandจะต้องใช้ชื่อของปฏิบัติการเป็นอาร์กิวเมนต์และมองมันได้ในและดำเนินการมันเคอร์เนลจะทำงานPATH /fixed/path/to/path-lookup-command python /path/to/scriptเมื่อมันเกิดขึ้นenvคำสั่งก็ทำเช่นนั้น วัตถุประสงค์หลักของมันคือการเรียกใช้คำสั่งที่มีสภาพแวดล้อมที่แตกต่างกัน แต่เนื่องจากมันค้นหาชื่อคำสั่ง$PATHมันจึงเหมาะสำหรับวัตถุประสงค์ของเราที่นี่

แม้ว่าจะไม่รับประกันอย่างเป็นทางการระบบ Unix ประวัติศาสตร์ที่จัดไว้ให้envในและระบบที่ทันสมัยได้เก็บสถานที่ที่แม่นยำเพราะใช้อย่างแพร่หลายของ/usr/bin #!/usr/bin/envดังนั้นในทางปฏิบัติวิธีการระบุว่าสคริปต์ต้องถูกดำเนินการโดย Python interpreter ที่ผู้ใช้ชื่นชอบ

#!/usr/bin/env python

2
อันไหนที่ชอบระหว่างenvและwhich? ตั้งแต่ที่จะได้รับการปฏิบัติที่มีสิทธิ์มากที่สุดจากสภาพแวดล้อมเส้นทางของฉัน
Nikhil Mulley

8
@NikhilMulley whichค้นหาไฟล์สั่งการและพิมพ์พา ธ envค้นหาโปรแกรมที่ระบุโดยอาร์กิวเมนต์แรกและเรียกใช้งานโดยส่งผ่านอาร์กิวเมนต์ที่เหลือ
เควิน

3
ดังนั้นมันenvจึงเป็นรุ่น Eval ของwhichหลัก
Nikhil Mulley

6

ถูกต้องแล้วเรียกใช้:

env | grep PATH

$ PATH ของคุณคือรายการไดเรกทอรี Unix จะผ่านรายการไดเรกทอรีตามลำดับจนกระทั่งพบ "python"

คุณสามารถดูว่าไดเรกทอรีใดที่ค้นหาด้วยคำสั่ง 'which':

which python

น่าสนใจฉันเห็นความแตกต่างของงูหลามsys.pathระหว่าง env $ env python3 ( ['', '/home/user/test', '/usr/lib/python3.4', '/usr/lib/python3.4/plat-x86_64-linux-gnu', '/usr/lib/python3.4/lib-dynload', '/home/user/.local/lib/python3.4/site-packages', '/usr/lib/python3.4/site-packages', '/usr/local/lib/python3.4/dist-packages', '/usr/lib/python3/dist-packages']) และ./env/bin/python3 (['', '/home/user/test', '/usr/lib/python3.4', '/usr/lib/python3.4/plat-x86_64-linux-gnu', '/usr/lib/python3.4/lib-dynload', '/home/user/test/env3/lib/python3.4/site-packages']) ที่เปิดใช้งาน
ThorSummoner
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.