ทำไมฉันต้องใส่ sh ก่อนที่จะเรียกใช้ไฟล์. sh


16

เมื่อฉันต้องการเรียกใช้.shไฟล์ใน Terminal ฉันต้องวางไว้shข้างหน้า

มีวิธีใดที่จะหลีกเลี่ยงปัญหานี้และทำให้ประหยัดการพิมพ์หรือไม่


3
ฉันสร้างโฟลเดอร์ที่ ~ / bin เพื่อใส่เชลล์สคริปต์ลงในและวางไว้บน $ PATH ของฉันและยังแนบ Folder Action ไปยังโฟลเดอร์ ~ / bin เพื่อตั้งค่าการอนุญาตให้ใช้งานโดยอัตโนมัติเพราะมันง่ายที่จะลืม
Kaydell

คำตอบ:


22

หากคุณใช้งานสคริปต์ของคุณจากเปลือกคุณไม่จำเป็นต้องมี#!/bin/shshebang ตามที่ระบุไว้ในคำตอบนี้ - ทุกระบบที่ใช้ Unix เหมือนที่ฉันเคยใช้รวมถึง OS X จะเป็นค่าเริ่มต้น/bin/shหากไม่มีล่ามเฉพาะเจาะจง ( แม้ว่าจะเป็นความคิดที่ดีเพราะไม่ใช่ผู้ใช้เชลล์จะไม่ทราบวิธีการเรียกใช้งานสคริปต์ของคุณเว้นแต่คุณจะให้เงินแก่ shebang)

คุณไม่จำเป็นต้องมี.shส่วนขยาย คุณทำจำเป็นต้องตั้งค่าสิทธิ์ที่ปฏิบัติการเช่น

$ chmod +x script.sh

(นี่$คือเชลล์พรอมต์ฉันใช้มันเพื่อแสดงคำสั่งที่คุณให้กับเชลล์เชิงโต้ตอบอย่าพิมพ์!)

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

$ cat >script.sh
echo hello, world
^D
$ chmod +x script.sh
$ script.sh
-bash: script.sh: command not found

( ^Dหมายถึงcontrol- D. คุณจะพบสัญกรณ์นี้ในการเขียนจำนวนมากเกี่ยวกับการใช้ Unix)

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

$ sh script.sh
hello, world

เพราะshใช้สคริปต์เป็นอาร์กิวเมนต์

คุณสามารถเรียกใช้งานสคริปต์ - หรืออีกครั้งใด ๆ ที่รันได้ - ในไดเรกทอรีปัจจุบันหากมีการทำเครื่องหมายปฏิบัติการ (เช่นchmod +x) โดยการระบุว่าคุณต้องการเรียกใช้หนึ่งในไดเรกทอรีปัจจุบัน:

$ ./script.sh
hello, world

PATHนอกจากนี้คุณยังสามารถย้ายสคริปต์ไปยังไดเรกทอรีบน ฉันขอแนะนำให้/usr/local/binใช้สิ่งนี้หากสคริปต์ของคุณตั้งใจจะใช้ทั่วทั้งระบบหรือbinไดเรกทอรีในบ้านของคุณหากสคริปต์นั้นเหมาะสำหรับคุณเท่านั้น สิ่งหลังต้องการให้คุณเพิ่ม$HOME/binซึ่งขยายไปยังไดเรกทอรี bin ใหม่ของคุณPATHโดยเพิ่มบรรทัดต่อไปนี้.profileในโฮมไดเร็กตอรี่ของคุณ:

PATH=$HOME/bin:$PATH
export PATH

ท้ายที่สุดคุณสามารถทำได้ถ้าคุณต้องการเพิ่มไดเรกทอรีปัจจุบันลงในของคุณPATHซึ่งจะช่วยให้คุณเพียงแค่ไปที่ไดเรกทอรีที่มีscript.sh- หรือไฟล์ปฏิบัติการอื่น - และพิมพ์

$ script.sh

เพื่อรันมัน แต่ผมไม่แนะนำให้ปฏิบัตินี้เป็นผู้โจมตีในขณะนี้สามารถหลอกให้คุณทำงานปฏิบัติการโดยพลการโดยการวางสคริปต์ปฏิบัติการ (ชื่อการพูด, ls) ลงในไดเรกทอรีคุณจะอยู่ใน. ถ้าคุณจริงๆต้องการที่จะทำ แต่ เพียงเพิ่มสิ่งต่อไปนี้ใน.profile:

PATH=.:$PATH
export PATH

ใส่ '.' ในตอนท้ายของ $ PATH แทนที่จะเป็นจุดเริ่มต้นและตอนนี้คุณไม่จำเป็นต้องกังวลเกี่ยวกับ phantom 'ls' (แม้ว่าจะมีใครบางคนสามารถเข้าสู่ระบบของคุณคุณมีปัญหาใหญ่กว่า)
TJ Luoma

2
@TJ แต่คุณไม่จำเป็นต้องกังวลเกี่ยวกับสิ่งที่ชอบslหรือllsหรือl... คือความผิดพลาด เพียงแค่ปล่อยออกมาจาก. $PATHนอกจากนี้คุณอาจไม่ (หรือไม่ควร) จำเป็นต้องเชื่อใจทุกคนในระบบของคุณ ตัวอย่างเช่นสมมติว่ามีช่องโหว่บางอย่างที่ทำให้ผู้โจมตีสามารถวางไฟล์โดยพลการลงในไดเรกทอรีบางตัว แต่พวกเขาต้องการให้คุณเรียกใช้ไฟล์นั้นเพื่อเพิ่มระดับการใช้ประโยชน์ที่ดีขึ้น (เช่นรวบรวมข้อมูลและโทรศัพท์กลับบ้าน) การป้องกันในเชิงลึก!
Reid

@TJLuoma สิ่งที่ @Reid พูดและโปรดจำไว้ว่ามีกรณีการใช้งานมากมายสำหรับระบบ Unix นอกเหนือจากเดสก์ท็อป OS X ส่วนบุคคล ยังไม่ได้ลอง แต่ฉันเดิมพันแม้กระทั่งบัญชีผู้เยี่ยมชมสามารถทิ้งหนึ่งในรายการเหล่านั้นใน/tmpหรือไดเรกทอรีอื่น ๆ ที่เขียนได้ทั่วโลก
zigg

หากคุณใช้ระบบที่คนอื่นสามารถเข้าถึงไดเรกทอรีที่คุณใช้คุณจะพบปัญหาที่ใหญ่กว่า
TJ Luoma

@TJLuoma คุณไม่ควรใช้หลายบัญชีในระบบ Unix ใด ๆ /tmpet al. มาพร้อมกับดินแดน
zigg

10

คุณไม่จำเป็นต้องโทรshหากไฟล์สคริปต์ถูกทำเครื่องหมายว่าสามารถทำงานได้ ในกรณีนี้คุณสามารถเรียกมันว่าชื่อของฉันเหมือนกับที่คุณทำกับคำสั่งอื่นจากเชลล์ที่มีอยู่


เพื่อให้เหมาะสมอย่างสมบูรณ์คุณจะต้องทำสองสิ่ง:

  1. แก้ไขสคริปต์ของคุณเพื่อรวมคำสั่งshebangที่ด้านบนของสคริปต์ของคุณ:

    #!/bin/sh

    ... นั่นจะบอกเชลล์ว่าล่ามคนไหนที่ใช้ในการเรียกใช้สคริปต์ ในกรณีนี้การ/bin/shปฏิบัติการ

  2. ทำเครื่องหมายสคริปต์ว่าสามารถเรียกทำงานได้โดยคุณด้วยคำสั่งchmod :

    chmod u+x scriptname.sh

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


Shebangs ไม่จำเป็นจริง ๆ/bin/shแม้ว่าพวกเขาจะไม่เจ็บ
zigg

@zigg - คุณถูกต้อง ฉันหวังว่า Chris จะไม่สนใจการแก้ไขของฉัน ... Nuke หรือแก้ไขใหม่ตามที่ต้องการ: -0
bmike

@bmike การแก้ไขใช้งานได้สำหรับฉัน สำหรับ Shebangs นิสัยของฉันคือการระบุเสมอเพราะฉันเคยเขียนkshสคริปต์จำนวนมากในสมัยของฉันใน HP-UX - แต่มันก็ดีที่ได้รู้ว่ามันไม่จำเป็นอย่างยิ่ง
Chris W. Rea

1
ฉันคิดว่าฉันต้องการที่จะกลับออกไปจากคำสั่งก่อนหน้านี้ของฉันเกี่ยวกับความจำเป็น shebang ( แต่ส่วนที่เหลือของคำตอบของฉันยังคงยืน.) คุณสามารถเรียกใช้สคริปต์ shebang น้อยจากกะลา แต่ถ้าคุณใช้execsyscall คุณจะได้รับENOEXECข้อผิดพลาด (รูปแบบ exec ) ขออภัยเกี่ยวกับสิ่งนั้น @bmike, @ ChrisW.Rea ฉันจะไปแก้ไขคำตอบของฉันตอนนี้
zigg
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.