./ vs สำหรับการรันโปรแกรมภายใต้เทอร์มินัล


13

ฉันต้องการคำอธิบายเกี่ยวกับวิธีที่เราเรียกใช้โปรแกรมเรียกทำงานภายใต้ Terminal นี่อาจเป็นคำถามง่อย แต่ความแตกต่างระหว่างการใช้งานโปรแกรมเรียกทำงานกับ./an_executableและ. an_executable(สมมติว่าเราอยู่ใน dir ที่มี an_executable ตั้งอยู่)

ฉันรู้แล้วว่าอดีตทำให้เชลล์ค้นหา an_executable ในไดเรกทอรีปัจจุบัน ( .) แต่ทำไมไม่/จำเป็นหลังจาก.ใช้เวอร์ชันหลัง?

ขอบคุณล่วงหน้า.


ดูเพิ่มเติมaskubuntu.com/q/182012/26972
ysap

คำตอบ:


22

. executableไวยากรณ์ไม่ได้ทำงานกับเพียงใดปฏิบัติการ (หรือไม่ได้หรือไม่) แต่มันเป็นนามแฝงสำหรับ bash sourceในตัว ดังนั้นความแตกต่างส่วนใหญ่เกี่ยวข้องกับสคริปต์ทุบตีและความจริงก็คือพวกมันต่างกันโดยสิ้นเชิง :)

./executableขอให้เรียกใช้ปฏิบัติการ "ปกติ" ./เป็นการอ้างอิงแบบสัมพัทธ์กับพา ธ ปัจจุบัน วิธีนี้จะหลีกเลี่ยงการมีเชลล์ (ทุบตี) พยายามค้นหาไฟล์ที่เรียกใช้งานได้ในไดเรกทอรีที่อยู่$PATH(ซึ่งจะทำถ้าคุณไม่ได้ระบุพา ธ เลยด้วยคำสั่ง) เหตุผลที่คุณไม่สามารถทำได้เพียงexecutableเพราะความปลอดภัย lsคิดคุณยกเลิกการบีบอัดข้อมูลที่เก็บคุณดาวน์โหลดและจะมีรุ่นที่เป็นอันตรายของ หากเรียกใช้โดยตรงจากไดเรกทอรีปัจจุบันของคุณคุณจะต้องเรียกใช้เวอร์ชันนั้นโดยไม่ทราบ

ในทางตรงกันข้าม. executableจะพูดว่า "แหล่งไฟล์ชื่อexecutable" เนื่องจากคุณตั้งชื่อไฟล์โดยตรงและไม่จำเป็นต้องเป็นไฟล์ปฏิบัติการข้อ จำกัด ด้านความปลอดภัยสำหรับ $ PATH จึงไม่สามารถใช้งานได้ การจัดหาจะเชลล์สคริปต์ "รัน" (หรือดูเหมือนว่าจะทำงาน) เท่านั้น มันคืออะไร:

   source filename [arguments]
          Read and execute commands from filename  in  the  current  shell
          environment  and return the exit status of the last command exe‐
          cuted from filename.

ดังนั้น ... อะไรคือความแตกต่างระหว่างการดำเนินการและการจัดหา? สมมติว่าเชลล์สคริปต์เดียวกันทำงานมัน ( ./script) จะวางไข่เชลล์ใหม่รันสคริปต์ภายในเชลล์นั้นและเมื่อสคริปต์ออกให้ปิดเชลล์นั้นแล้วกลับไปที่พาเรนต์เชลล์ ผลก็จะเริ่มbashกระบวนการใหม่เพื่อรันสคริปต์)

( . script) จะทำให้เชลล์ปัจจุบันอ่านคำสั่งจากไฟล์ราวกับว่าพวกมันถูกพิมพ์ในบรรทัดคำสั่ง ไม่มีกระสุนใหม่เกิดขึ้น

exitวิธีที่ง่ายมากที่จะดูว่าจะทำงานนี้คือการเขียนสคริปต์ที่มีเพียง หากคุณ./scriptดูเหมือนจะไม่มีอะไรเกิดขึ้นนี่เป็นเพราะกระบวนการเชลล์ใหม่เริ่มต้นขึ้นexitคำสั่งจะออกจากเชลล์ใหม่และเชลล์ปัจจุบันของคุณที่ไม่ได้รับผลกระทบ

หากคุณ. scriptคุณเทอร์มินัลปัจจุบันจะปิดลงเนื่องจากexitคำสั่งรันในเชลล์ปัจจุบัน ดังนั้นจึงเทียบเท่ากับการพิมพ์exitบนพรอมต์คำสั่ง


ที่จริงฉันจัดการกับเชลล์สคริปต์เมื่อฉันสังเกตเห็นพฤติกรรมนี้ ขอบคุณมากนั่นคือคำตอบที่ฉันต้องการ :)
zipzap

อีกคำถามที่ยกขึ้นมา (ถ้าคุณไม่เป็นไร): ถ้าสคริปต์ของฉันมีเพียงข้อความง่ายๆที่มี echo และฉันกำลังรันด้วย. /script เหตุใดฉันจึงสามารถเห็นข้อความในเชลล์พาเรนต์ถ้า subshell ปิด ทันทีที่การดำเนินการสิ้นสุดลง?
zipzap

2
เนื่องจากในขณะที่ subshell เป็นกระบวนการแยกต่างหากมันใช้เทอร์มินัลเดียวกันกับเชลล์ที่กล่าวอ้าง มันคล้ายกับวิธีที่คุณยังสามารถเห็นlsเอาต์พุต: คุณพิมพ์คำสั่งมันรันแสดงผลลัพธ์แล้วมันจะจบลง แต่เอาต์พุตยังคงอยู่ในเทอร์มินัล
roadmr

2
อย่าสับสนกับเชลล์ด้วยเทอร์มินัล พวกมันต่างกัน เปิดเทอร์มินัลและพร้อมรับคำสั่งจากbashเชลล์ที่รันอยู่ภายใน หากคุณพิมพ์bashคุณจะเรียกใช้เชลล์อื่น สำหรับเชลล์ตัวแรกมันเป็นแค่โปรแกรมที่จะทำงาน หากคุณพิมพ์exitคุณจะปิดเชลล์สุดท้ายที่คุณเริ่ม แต่ยังคงอยู่ในเชลล์แรก ทั้งหมดนี้เกิดขึ้นภายในอาคารเดียวกัน
roadmr

1
@DavidZ ฉันพูดถึงมัน :) "การจัดหาจะ" เรียกใช้ "สคริปต์เชลล์ (หรือดูเหมือนจะรัน) เท่านั้น"
roadmr
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.