ทุกคนสามารถอธิบายการใช้คำสั่ง exec ในเชลล์สคริปต์ด้วยตัวอย่างง่ายๆได้อย่างไร?
ทุกคนสามารถอธิบายการใช้คำสั่ง exec ในเชลล์สคริปต์ด้วยตัวอย่างง่ายๆได้อย่างไร?
คำตอบ:
exec
ฟังก์ชั่นในตัวกระจกคำสั่งใน kernel มีครอบครัวของพวกเขาอยู่บนพื้นฐานexecve
ซึ่งมักจะถูกเรียกจากซี
exec
แทนที่โปรแกรมปัจจุบันในกระบวนการปัจจุบันโดยไม่ต้องfork
ใช้กระบวนการใหม่ ไม่ใช่สิ่งที่คุณจะใช้ในทุกสคริปต์ที่คุณเขียน แต่มันมีประโยชน์ในบางโอกาส นี่คือบางสถานการณ์ที่ฉันใช้
เราต้องการให้ผู้ใช้เรียกใช้โปรแกรมแอปพลิเคชันเฉพาะโดยไม่ต้องเข้าถึงเชลล์ เราสามารถเปลี่ยนโปรแกรมลงชื่อเข้าใช้ใน / etc / passwd แต่บางทีเราต้องการให้การตั้งค่าสภาพแวดล้อมถูกใช้จากไฟล์เริ่มต้น ดังนั้นใน (พูด) .profile
คำสั่งสุดท้ายพูดว่า:
exec appln-program
ดังนั้นตอนนี้ไม่มีกระสุนให้กลับไป แม้ว่าจะappln-program
ขัดข้องผู้ใช้ปลายทางก็ไม่สามารถไปถึงเชลล์ได้เพราะมันไม่ได้อยู่ที่นั่น - exec
มันถูกแทนที่
เราต้องการใช้เชลล์ที่แตกต่างกับหนึ่งใน / etc / passwd โง่อย่างที่เห็นบางเว็บไซต์ไม่อนุญาตให้ผู้ใช้เปลี่ยนเชลล์การลงชื่อเข้าใช้ เว็บไซต์หนึ่งฉันรู้ว่ามีการเริ่มต้นทุกคนที่มีcsh
และทุกคนก็ใส่ลงไปในของพวกเขา.login
(ไฟล์เริ่มต้นขึ้น csh) ksh
เรียกร้องให้ ในขณะที่ทำงานมันออกจากcsh
กระบวนการหลงทางที่ทำงานและออกจากระบบเป็นสองขั้นตอนซึ่งอาจทำให้เกิดความสับสน ดังนั้นเราจึงเปลี่ยนเป็นโปรแกรมexec ksh
ที่แทนที่ c-shell ด้วย korn เชลล์และทำให้ทุกอย่างง่ายขึ้น (มีปัญหาอื่น ๆ เช่นสิ่งksh
นี้ไม่ใช่ความจริงว่าlogin-shell)
เพียงเพื่อบันทึกกระบวนการ หากเราโทรหาprog1 -> prog2 -> prog3 -> prog4
ฯลฯ และไม่ย้อนกลับไปให้ทำการเรียก exec ทุกครั้ง มันช่วยประหยัดทรัพยากร (ไม่มากยอมรับได้เว้นแต่จะทำซ้ำ) และทำให้การปิดเครื่องง่ายขึ้น
เห็นได้ชัดว่าคุณเคยเห็นมีการexec
ใช้งานที่ไหนสักแห่งบางทีถ้าคุณแสดงรหัสที่คุณใช้เราก็สามารถพิสูจน์ได้ว่าเป็นการใช้งาน
แก้ไข : ฉันรู้ว่าคำตอบข้างต้นไม่สมบูรณ์ มีอยู่สองวิธีที่ใช้exec
ในเชลล์เช่นksh
และbash
- ใช้สำหรับเปิดไฟล์ descriptors นี่คือตัวอย่างบางส่วน:
exec 3< thisfile # open "thisfile" for reading on file descriptor 3
exec 4> thatfile # open "thatfile" for writing on file descriptor 4
exec 8<> tother # open "tother" for reading and writing on fd 8
exec 6>> other # open "other" for appending on file descriptor 6
exec 5<&0 # copy read file descriptor 0 onto file descriptor 5
exec 7>&4 # copy write file descriptor 4 onto 7
exec 3<&- # close the read file descriptor 3
exec 6>&- # close the write file descriptor 6
โปรดทราบว่าระยะห่างมีความสำคัญมากที่นี่ หากคุณเว้นช่องว่างระหว่างหมายเลข fd และสัญลักษณ์การเปลี่ยนเส้นทางแล้วเปลี่ยนexec
เป็นความหมายดั้งเดิม:
exec 3 < thisfile # oops, overwrite the current program with command "3"
มีหลายวิธีที่คุณสามารถใช้สิ่งเหล่านี้ในการใช้ ksh read -u
หรือprint -u
บนbash
ตัวอย่างเช่น:
read <&3
echo stuff >&4
exec gunicorn
ให้ pid ที่ถูกต้องกลับไปยังหัวหน้างาน
exec
สามารถนำมาใช้สำหรับการเปลี่ยนเส้นทาง:> ถ้าคำสั่งไม่ได้ระบุการเปลี่ยนเส้นทางใด ๆ ที่มีผลบังคับใช้ในเปลือกปัจจุบันและสถานะการส่งกลับเป็น 0 หากมีข้อผิดพลาดการเปลี่ยนเส้นทางสถานะกลับเป็น 1 แต่วิธีการที่ไม่exec
ใช้งานได้จริงเพื่อเปลี่ยน file descriptor? เหตุใดจึงเลือกคำสั่งนี้สำหรับงานนี้ (Markdown ล้มเหลวในขณะนี้?)
exec >.\logfilename.log 2>&1
&>
เป็นbash
ส่วนขยาย (ดูman bash
) exec >/var/log/userdata.log 2>&1
และตัวอย่างของคุณจะเทียบเท่ากับ กล่าวอีกนัยหนึ่งมันเปลี่ยนเส้นทาง stdout และ stderr ไปยังไฟล์นั้น คำสั่งที่ตามมาจะสืบทอดการเปลี่ยนเส้นทางเหล่านั้นยกเว้นว่ามีการรีเซ็ต แต่จะถูกดำเนินการ
เพียงเพื่อเพิ่มคำตอบที่ได้รับการยอมรับกับคำตอบสั้น ๆ สั้น ๆ exec
มือใหม่ง่ายคุณอาจไม่จำเป็นต้อง
หากคุณยังอยู่ที่นี่การสนทนาต่อไปนี้ควรจะเปิดเผยว่าทำไม เมื่อคุณวิ่งพูด
sh -c 'command'
คุณเรียกใช้sh
อินสแตนซ์จากนั้นเริ่มcommand
เป็นลูกของsh
อินสแตนซ์นั้น เมื่อcommand
เสร็จสิ้นsh
อินสแตนซ์ก็จะเสร็จสิ้น
sh -c 'exec command'
เรียกใช้sh
อินสแตนซ์จากนั้นแทนที่sh
อินสแตนซ์นั้นด้วยcommand
ไบนารีและเรียกใช้งานแทน
แน่นอนว่าสิ่งทั้งสองนี้ไร้ประโยชน์ในบริบทที่ จำกัด นี้ คุณเพียงแค่ต้องการ
command
command
มีบางสถานการณ์ที่ขอบที่คุณต้องการเปลือกในการอ่านแฟ้มการกำหนดค่าหรืออย่างใดอย่างอื่นตั้งค่าสภาพแวดล้อมเช่นการเตรียมความพร้อมสำหรับการทำงานที่มี นี่เป็นสถานการณ์เดียวที่exec command
ค่อนข้างมีประโยชน์
#!/bin/sh
ENVIRONMENT=$(some complex task)
exec command
สิ่งนี้ทำบางสิ่งบางอย่างเพื่อเตรียมสภาพแวดล้อมเพื่อให้มีสิ่งที่จำเป็น เมื่อดำเนินการเสร็จสิ้นsh
อินสแตนซ์นั้นไม่จำเป็นอีกต่อไปดังนั้นจึงเป็นการเพิ่มประสิทธิภาพ (เล็กน้อย) เพื่อแทนที่sh
อินสแตนซ์ด้วยcommand
กระบวนการแทนที่จะsh
เรียกใช้เป็นกระบวนการลูกและรอให้มันออกแล้วออกจากทันทีที่เสร็จสิ้น
ในทำนองเดียวกันถ้าคุณต้องการเพิ่มทรัพยากรให้มากที่สุดเท่าที่จะเป็นไปได้สำหรับคำสั่ง heavyish ที่ส่วนท้ายของเชลล์สคริปต์คุณอาจต้องการexec
คำสั่งนั้นเป็นการปรับให้เหมาะสม
หากกองกำลังบางสิ่งบางอย่างให้คุณสามารถทำงานsh
แต่คุณอยากจะทำงานอย่างอื่นexec something else
เป็นของหลักสูตรการแก้ปัญหาที่จะเปลี่ยนที่ไม่พึงประสงค์sh
เช่น (อย่างเช่นถ้าคุณอยากจะทำงานเรียบร้อยของตัวเองgosh
แทนsh
แต่คุณไม่ได้อยู่ใน/etc/shells
เพื่อให้คุณสามารถ ไม่ได้ระบุว่าเป็นเปลือกเข้าสู่ระบบของคุณ)
การใช้งานครั้งที่สองexec
เพื่อจัดการไฟล์ descriptors เป็นหัวข้อแยกต่างหาก คำตอบที่ได้รับการยอมรับนั้นครอบคลุมอย่างดี เพื่อให้มีอยู่ในตัวเองฉันจะเพียงแค่เลื่อนไปที่คู่มือสำหรับสิ่งที่exec
ตามด้วยการเปลี่ยนเส้นทางแทนชื่อคำสั่ง