Shebang และเส้นทาง


22

ทำไมกลุ่มแม่บ้านต้องการเส้นทาง?

ไม่ถูกต้อง

#!ruby

แก้ไข

#!/usr/local/bin/ruby

#!/usr/bin/env ruby

ระบบปฏิบัติการควรมีข้อมูลเกี่ยวกับพา ธ สำหรับคำสั่งที่ลงทะเบียนแล้วและทำไมมันยังคาดหวังว่าจะได้รับ?

คำตอบ:


22

อาจทำให้เคอร์เนลง่ายขึ้น ฉันไม่คิดว่าเคอร์เนลจะค้นหาเส้นทางของคุณเพื่อค้นหาสิ่งที่เรียกใช้งานได้ ถูกจัดการโดย C library #!การประมวลผลเสร็จในเคอร์เนลซึ่งไม่ได้ใช้ไลบรารี C มาตรฐาน

นอกจากนี้ฉันไม่คิดว่าเคอร์เนลมีความคิดว่าเส้นทางของคุณคืออะไร $PATHเป็นตัวแปรสภาพแวดล้อมและกระบวนการเท่านั้นที่มีสภาพแวดล้อม เคอร์เนลไม่ได้ ฉันคิดว่ามันสามารถเข้าถึงสภาพแวดล้อมของกระบวนการที่ทำ exec แต่ฉันไม่คิดว่าสิ่งใดในเคอร์เนลที่เคยเข้าถึงตัวแปรสภาพแวดล้อมเช่นนั้น


5

คุณสามารถรับ - การPATHค้นหาความหมายโดยใช้envดังนั้น:

#!/usr/bin/env ruby  

มีความหมายที่คุณต้องการจาก

#!ruby

เหตุผลที่ขึ้นอยู่กับPATHไม่ถือว่าเป็นแนวปฏิบัติที่ดีคือสคริปต์ไม่สามารถทำการสันนิษฐานเกี่ยวกับเนื้อหาของตัวแปรสภาพแวดล้อม PATH ได้ทำลาย "รูปแบบการพึ่งพาตามลำดับ" ของไบนารีที่

  1. /bin มีไฟล์เรียกทำงานที่จำเป็นในเวลาบูต
  2. /usr/bin มีไฟล์ปฏิบัติการอื่น ๆ ที่ใช้โดยการติดตั้งระบบปฏิบัติการ;
  3. /usr/local/bin มีไฟล์ปฏิบัติการที่ติดตั้งโดยผู้ดูแลระบบที่ไม่ได้เป็นส่วนหนึ่งของระบบปฏิบัติการพื้นฐาน
  4. ~/bin มีไฟล์ปฏิบัติการของผู้ใช้

แต่ละระดับไม่ควรสันนิษฐานว่ามีไบนารีอยู่ในลำดับต่อมาซึ่งเป็น "แอปพลิเคชัน" มากกว่า แต่อาจขึ้นอยู่กับไบนารีก่อนหน้าซึ่งเป็น "พื้นฐาน" มากกว่า และตัวแปร PATH มีแนวโน้มที่จะเรียกใช้จากแอ็พพลิเคชันถึงพื้นฐานซึ่งเป็นทิศทางตรงกันข้ามกับการพึ่งพาธรรมชาติข้างต้น

เพื่อแสดงให้เห็นถึงปัญหาถามตัวเองว่าจะเกิดอะไรขึ้นถ้าสคริปต์ในการ~/binเรียกใช้สคริปต์ในการ/usr/local/binที่เรียกว่าทับทิม? ควรสคริปต์ที่ขึ้นอยู่กับระบบปฏิบัติการรุ่นที่ติดตั้งใน/usr/bin/rubyหรือบนสำเนาส่วนบุคคลของผู้ใช้ที่เกิดขึ้นจะมีที่~/bin/ruby? PATHการค้นหาให้ความหมายที่ไม่อาจคาดเดาได้ที่เกี่ยวข้องกับสิ่งหลัง (อาจ~/bin/rubyเป็นการเชื่อมโยงสัญลักษณ์ที่ใช้งานไม่ได้) ในขณะที่การอบในเส้นทางเพื่อ#!ให้อดีต

มีไม่ได้จริงๆใด ๆ แพลตฟอร์ม "ระบบปฏิบัติการ ... ข้อมูลเกี่ยวกับเส้นทางสำหรับคำสั่งที่ลงทะเบียน" อื่น ๆ #!ดังนั้นสิ่งที่ง่ายที่สุดคือการยืนยันในเส้นทางที่ถูกระบุไว้ใน


0

ฉันเชื่อว่าเป็นเช่นนั้นคุณสามารถระบุล่ามทางเลือกได้หากคุณต้องการหรือต้องการ ตัวอย่างเช่น:

#!/home/user/myrubyinterpreter

เห็นบ่อยขึ้นด้วยเชลล์สคริปต์:

#!/bin/bash
#!/bin/sh
#!/bin/dash
#!/bin/csh

4
แต่ทำไมถึงทำให้จำเป็น? คุณสามารถเรียกใช้ ruby ​​โดยตรงด้วยrubyแต่นั่นไม่ได้หยุดคุณจากการระบุ/home/user/myrubyinterpreterว่าคุณต้องการ
Michael Mrozek

ประเด็นของไมเคิลคือสิ่งที่ฉันต้องการ
sawa

0

จากหนังสือClassic Shell Scripting :

#! /bin/shเชลล์สคริปต์มักจะเริ่มต้นด้วย ใช้พา ธ ไปยังเชลล์ที่เข้ากัน/bin/shได้กับ POSIX หากคุณไม่ใช่ POSIX นอกจากนี้ยังมี "gotchas" ระดับต่ำที่ควรระวัง:

  • คุณต้องรู้ชื่อพา ธ เต็มรูปแบบของล่ามที่จะเรียกใช้ นี้สามารถป้องกันการพกพาข้ามผู้ผลิตตั้งแต่ผู้ผลิตที่แตกต่างกันนำสิ่งที่อยู่ในสถานที่ที่แตกต่างกัน (เช่น/bin/awkเมื่อเทียบกับ/usr/bin/awk)

-2

มีเหตุผลอื่น ๆ แต่จากมุมมองด้านความปลอดภัยฉันไม่ต้องการให้สคริปต์เขียนสมมติฐานเกี่ยวกับเส้นทางที่ถูกต้อง เกิดอะไรขึ้นถ้ามันผิดและมันรันเชลล์หรือล่ามที่ผิด? ผู้ใช้ที่ประสงค์ร้ายถูกแทรกไว้หรือไม่ หรือเกิดอะไรขึ้นถ้ามันต้องอาศัยเชลล์ตัวใดตัวหนึ่งและจะเกิดความผิดพลาดถ้าใช้เชลล์ที่ผิด?

ผู้ใช้อาจยุ่งกับเส้นทางของพวกเขาและทำลายสิ่งต่าง ๆ - อย่าไว้ใจผู้ใช้ :-) ฉันได้ทำการโจมตีหลายครั้งซึ่งพึ่งพาผู้ใช้ที่ทำสิ่งที่ผิดกับเส้นทางของพวกเขา - มักจะได้รับสิ่งต่าง ๆ ในลำดับที่ผิด - การเรียกใช้สคริปต์ปกติ

ใช่ฉันรู้ว่าคุณเขียนสคริปต์ด้วยตัวเองคุณสามารถอ้างสิทธิ์ได้อย่างถูกต้องว่าคุณได้แยกเส้นทางของคุณเอง แต่ล่ามไม่สามารถตัดสินใจได้


ข้อกังวลนี้มีผลเฉพาะในกรณีที่สคริปต์ทำงานด้วยสิทธิ์ระดับสูง และนั่นก็เป็นเรื่องแปลกเพราะ shebang และ setxid $PATHไม่ได้เล่นร่วมกันได้ดีและมีจำนวนมากขึ้นที่จะต้องกังวลเกี่ยวกับกว่า . หากไม่มีสิทธิ์ยกระดับจะเกิดอะไรขึ้นถ้าLD_PRELOADมีการใช้งาน PS Downvoted เนื่องจากการแจ้งเตือนที่ผิดพลาดเกี่ยวกับความปลอดภัยนั้นเป็นอันตรายต่อความปลอดภัย
Gilles 'หยุดความชั่วร้าย'

จุดของคุณเกี่ยวกับ setxid นั้นถูกต้อง แต่มันเป็นเวคเตอร์การโจมตีที่มีประโยชน์อย่างสมบูรณ์ดังนั้นแน่นอนว่าไม่ใช่คำเตือนที่ผิดพลาด
Rory Alsop

1
คุณสามารถยกตัวอย่างของกรณีที่PATHมีเวกเตอร์โจมตีและไม่มีเวกเตอร์โจมตีอื่น ๆ อีกมากมายที่ควรจะพิจารณาแนวทางทั้งหมด
Gilles 'หยุดความชั่วร้าย'

@Gilles - +1 คุณมีจุดที่ดีแน่นอนว่าถ้ามีการแตกอาจมีวิธีอื่น ๆ ในการที่ถูกต้อง แต่ในแง่ของสิ่งที่แตกหักคุณสามารถแก้ไขได้นี่เป็นเรื่องง่าย
Rory Alsop
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.