การเรียกสคริปต์ด้วย. /bla.sh เทียบกับ bla.sh


11

ใครช่วยอธิบายสิ่งที่เชลล์ทำในสองตัวอย่าง A) และ B) ด้านล่างได้ไหม เห็นได้ชัดว่ามันทำงานแตกต่างกัน แต่ฉันไม่สามารถหาได้ว่าทำไมเอาต์พุตจึงแตกต่างกัน

ตัวอย่าง:
เรามามีสคริปต์ในไดเรกทอรีปัจจุบันของเราชื่อbla.shด้วยคำสั่งเดียว:
echo ${0##/*} hello

A)
เริ่มเมื่อ: ./bla.sh
ให้:./bla.sh hello

B)
เริ่มต้นเป็น: . bla.sh
ให้:-bash hello

เนื่องจากฉันใช้สิ่งนี้ในสคริปต์เอาต์พุตที่สอง (เพราะ "-" ที่ด้านหน้าของ -bash) จะฆ่าคำสั่ง แน่นอนง่าย ๆ--ก่อนที่จะ${...}ช่วยเหลือ แต่ฉันชอบที่จะเข้าใจสิ่งที่ทำให้เกิดผลลัพธ์ในครั้งแรก
ฉันรักทุบตี และ vi [m] แต่ฉันเชือนแช ...

คำตอบ:


22
./bla.sh

./bla.shนี่เป็นคำสั่ง สิ่งนี้ทำให้เชลล์มองหาไฟล์เรียกทำงานที่มีชื่อbla.shในไดเร็กทอรีปัจจุบันจากนั้นให้เคอร์เนลรันเป็นโปรแกรมปกติในกระบวนการแยกจากเชลล์ (ไม่สำคัญว่าbla.shจะเป็นbashสคริปต์หนึ่งperlหรือpythonหนึ่งหรือไบนารีที่คอมไพล์แล้ว)


. bla.sh

ที่นี่คำสั่งคือ.(aka source) คำสั่งในตัวของเชลล์ของคุณ มันทำให้เชลล์มองหาไฟล์ที่มีชื่อbla.shอยู่ใน system path ($ PATH) และตีความเนื้อหาราวกับว่าคุณพิมพ์ ทั้งหมดนี้ทำในกระบวนการเดียวกับตัวเชลล์ (และอาจส่งผลกระทบต่อสถานะภายในของเชลล์)

หลักสูตรนี้ใช้งานได้เฉพาะเมื่อbla.shมีคำสั่งสำหรับbashเชลล์ (หากเป็นคำสั่งที่คุณใช้อยู่) มันจะไม่ทำงานกับperlสคริปต์หรือสิ่งอื่นใด

(นี่คือคำอธิบายในhelp .และhelp sourceเกินไป)


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


โดยปกติแล้ววิธีที่ดีที่สุดคือใช้./bla.shวิธีนี้ เท่านั้น~/.bashrc, ~/.profileและไฟล์ดังกล่าวมักจะมาเพราะพวกเขาควรจะปรับเปลี่ยนสภาพแวดล้อมในปัจจุบัน


3
นอกจากนี้หากคุณเปลี่ยนสภาพแวดล้อมทุบตีใน bla.sh การเปลี่ยนแปลงเหล่านี้จะถูกนำมาพิจารณาภายหลัง bla.sh แต่ไม่ใช่หลังจาก. / bla.sh นี้เป็นเพราะ . bla.sh ทำงานในบริบทของ bash ปัจจุบันในขณะที่. / bla.sh ทำงานเป็น subprocess
mouviciel

1
ดูmywiki.wooledge.org/BashFAQ/060สำหรับตัวอย่าง โปรดทราบว่าsourceเป็นนามแฝงทุบตีเพื่อ.ไม่ใช่ตรงกันข้ามและsourceจะไม่ทำงานในหอยอื่น ๆ
mrucci

7

./<cmd>จะดำเนินการ<cmd>โปรแกรมที่อยู่ในไดเรกทอรีปัจจุบันในกระบวนการใหม่ (แยก) มันจะต้องมีการปฏิบัติการ #!และยังสามารถอ่านได้มันเริ่มต้นด้วย

. <cmd>จะทำให้เชลล์ปัจจุบันของคุณดำเนินการเชลล์สคริปต์<cmd>ที่อยู่ใน$PATHไดเรกทอรีปัจจุบันของคุณหรือในกระบวนการเชลล์ปัจจุบัน มันจะต้องสามารถอ่านได้ sourceมันเป็นนามแฝงสำหรับคำสั่งเปลือก


-1 . <cmd>จะค้นหาโปรแกรมใน$PATHและหากไม่พบจากนั้นจะค้นหาในไดเรกทอรีปัจจุบัน
dogbane

@dogbane ใช่ฉันแก้ไขสิ่งนี้แล้ว
kmkaplan

FWIW ไม่ใช่หอยทั้งหมดที่จะค้นหา cwd สำหรับ sripts ที่มา zsh (อย่างน้อยกับการกำหนดค่าที่ฉันมี) ต้องการ. ./cmd
bstpierre

1
@bstpierre สิ่งนี้ดูเหมือนจะเป็นพื้นเคลื่อนไหว การอ้างอิง POSIX ฉันได้กล่าวว่า“ เชลล์จะใช้พา ธ การค้นหาที่ระบุโดย PATH” และ“ การใช้งานที่เก่ากว่านั้นค้นหาไดเรกทอรีปัจจุบันสำหรับไฟล์แม้ว่าค่าของ PATH จะไม่อนุญาตก็ตาม”
kmkaplan

1

./cmd ใช้เส้นทางที่ชัดเจน ( ./- ปัจจุบัน dir) เพื่อปฏิบัติการ #!และมันก็ไม่จำเป็นที่จะเริ่มต้นด้วย

. cmd- (aka source) - คำสั่ง bash builtin ความแตกต่างที่เห็นได้อย่างหนึ่งของการดำเนินการผ่านsourceคือมันสามารถตั้งค่า / แก้ไขตัวแปรสภาพแวดล้อมของเชลล์ปัจจุบัน


แม่นยำยิ่งขึ้นsourceเป็นนามแฝงเพียงอย่างเดียวที่จะ.(ซึ่งเป็นมาตรฐาน)
1686

คุณพูดถูก แก้ไขแล้ว.
Leonid Volnitsky
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.