พิจารณาจากเอกสารของ Bash 'builtin exec:
exec แทนที่เชลล์โดยไม่ต้องสร้างกระบวนการใหม่
โปรดระบุกรณีการใช้งาน / ตัวอย่างการปฏิบัติ ฉันไม่เข้าใจว่าสิ่งนี้สมเหตุสมผลหรือไม่
ฉัน googled และพบเกี่ยวกับI / O เปลี่ยนเส้นทาง คุณช่วยอธิบายให้ดีขึ้นได้ไหม?
พิจารณาจากเอกสารของ Bash 'builtin exec:
exec แทนที่เชลล์โดยไม่ต้องสร้างกระบวนการใหม่
โปรดระบุกรณีการใช้งาน / ตัวอย่างการปฏิบัติ ฉันไม่เข้าใจว่าสิ่งนี้สมเหตุสมผลหรือไม่
ฉัน googled และพบเกี่ยวกับI / O เปลี่ยนเส้นทาง คุณช่วยอธิบายให้ดีขึ้นได้ไหม?
คำตอบ:
exec
มักจะใช้ในเชลล์สคริปต์ซึ่งส่วนใหญ่ทำหน้าที่เป็น wrappers สำหรับการเริ่มไบนารีอื่น ๆ ตัวอย่างเช่น:
#!/bin/sh
if stuff;
EXTRA_OPTIONS="-x -y -z"
else
EXTRA_OPTIONS="-a foo"
fi
exec /usr/local/bin/the.real.binary $EXTRA_OPTIONS "$@"
ดังนั้นหลังจากที่ wrapper รันเสร็จแล้วไบนารี "ของจริง" จะเข้ามาแทนที่และจะไม่มีการติดตามของสคริปต์ตัวตัดคำที่ครอบครองสล็อตเดียวกันชั่วคราวในตารางกระบวนการอีกต่อไป ไบนารี "ของจริง" เป็นลูกโดยตรงของอะไรก็ตามที่เปิดตัวแทนที่จะเป็นหลาน
คุณพูดถึงการเปลี่ยนเส้นทาง I / O ในคำถามของคุณด้วย นั่นเป็นกรณีการใช้งานที่แตกต่างออกไปexec
และไม่มีอะไรเกี่ยวข้องกับการแทนที่เชลล์ด้วยกระบวนการอื่น เมื่อexec
ไม่มีข้อโต้แย้งเช่นนั้น:
exec 3>>/tmp/logfile
ดังนั้นการเปลี่ยนทิศทาง I / O บนบรรทัดคำสั่งจะมีผลในกระบวนการเชลล์ปัจจุบัน แต่กระบวนการเชลล์ปัจจุบันยังคงทำงานอยู่และย้ายไปยังคำสั่งถัดไปในสคริปต์
exec
บอกให้เชลล์ไม่ทำการกระทำ (ดำเนินการคำสั่งหรือทำการเปลี่ยนเส้นทาง) ในกระบวนการลูก แต่อยู่ในกระบวนการเดียวกัน
ฉันใช้ shell exec
builtin เพื่อรับรหัสกระบวนการ (PID) ไปยังโปรแกรม Java อาจมีวิธีรับ PID จากภายใน Java ตอนนี้ แต่เมื่อหลายปีก่อนไม่มี เมื่อกระบวนการมี PID ของตัวเองก็สามารถเขียนออกไปที่ไฟล์ PID (ค้นหา/var/run/
ชื่อไฟล์ด้วยคำต่อท้าย '.pid') เพื่อให้โปรแกรมการจัดการทราบ PID ของกระบวนการทำงานและเพื่อป้องกันอินสแตนซ์ที่สอง ของเซิร์ฟเวอร์เดียวกันไม่ให้ทำงาน มันใช้งานได้เช่นนี้:
exec java -cp=YourServer.jar StartClass -p $$
รหัสในmain()
วิธีการเรียนStartClass
จัดการแยกวิเคราะห์อาร์กิวเมนต์และสามารถหา ID กระบวนการของตัวเอง
เพื่อความสนุกสนานให้เรียกใช้โปรแกรมต่อไปนี้ (แปลเป็นภาษาที่คุณเลือกใช้งาน) ในพื้นหลังในระบบที่มีการบัญชีและข้อ จำกัด ของกระบวนการผู้ใช้
while(true) fork();
ตอนนี้ทุกสล็อตในตารางกระบวนการที่คุณได้รับอนุญาตให้ใช้นั้นเต็มไปด้วยสำเนาของโปรแกรมที่รันอยู่คุณตั้งใจจะฆ่ามันอย่างไร การเปิดตัว kill (1) ต้องใช้สล็อตกระบวนการอื่นซึ่งคุณไม่มี มันจะเป็นประโยชน์หากมีเชลล์ที่จะแทนที่ตัวเองด้วยคำสั่ง kill ...
exec /bin/kill -9 -1
(สมมติว่าระบบของคุณมีการฆ่า (1) ที่ / bin / kill "exec` ซึ่ง kill` -9 -1 "อาจปลอดภัยกว่า) ซึ่งจะส่ง SIGKILL ไปยังทุกกระบวนการที่คุณทำได้
(หมายเหตุ: อย่าล็อกเอาต์จากเชลล์เรียกใช้งานของคุณเว้นแต่ว่าข้อ จำกัด ของกระบวนการจะอนุญาตให้ล็อกอินสล็อตใหม่สำหรับเชลล์ของกระบวนการซึ่งจะเป็นการยากมากขึ้นในการล้างหากคุณทำฉันไม่ได้ทำเช่นนี้ใน ต้นยุค 90 ไม่)
exec
คำสั่งที่เป็นประโยชน์ในสถานการณ์นี้ (2) คำตอบนี้ค่อนข้างล้าสมัย kill
คำสั่งที่ได้รับคำสั่ง builtin ในทุบตีเป็นเวลาหลายปีที่ผ่านมาส่วนใหญ่เนื่องจากความกังวลนี้
exec
- และความจริงที่ว่าkill
บิลท์อินนั้นไม่มีส่วนเกี่ยวข้องกับexec
บิลด์
`which kill`
) จะไม่ทำงานเช่นกัน (2) BTW $(…)
แนะนำให้ใช้`…`
แบบฟอร์มเหนือแบบฟอร์ม (3) แต่ไม่มีอันตรายใด ๆ เกี่ยวกับการคาดเดาที่ไดเรกทอรี หากคุณพิมพ์โดยไม่ตั้งใจexec /binn/kill
คุณจะได้รับข้อความแสดงข้อผิดพลาดและเปลือกของคุณจะไม่หายไป (4) แต่คุณไม่จำเป็นต้องกังวลว่าkill
จะ exec
ใช้ไดเร็กตอ$PATH
รี่อะไรเหมือนคำสั่งปกติ, ใช้exec kill …
งานได้ (สมมติว่าคุณมี/bin
ในพา ธ การค้นหา)
นี่คล้ายกับตัวอย่างของ Bruce ที่ต้องการทราบ PID ของกระบวนการ:
(cmdpid = $ BASHPID; (sleep 300; kill "$ cmdpid") & สั่งรันคำสั่งยาว )
ที่คุณ
(
และ)
)$$
จะให้ PID ของเชลล์หลัก)สิ่งนี้จะทำงานlong-running-command
แต่สำหรับระยะเวลาที่กำหนดไว้ล่วงหน้าที่ จำกัด ไว้เท่านั้น
นี้เป็นเล็ก ๆ น้อย ๆ เล็ก ๆ น้อย ๆ แต่ถ้าคุณตัดสินใจว่าคุณต้องการที่จะเป็นราก (หรือบางส่วนของผู้อื่น) exec su
สำหรับส่วนที่เหลือของเซสชั่นการเข้าสู่ระบบของคุณคุณจะทำได้
จริงๆแล้วฉันสามารถจินตนาการถึงสถานการณ์ที่สิ่งนี้จะมีประโยชน์จริงๆ สมมติว่าคุณเข้าสู่ระบบระยะไกลและด้วยเหตุผลบางประการมีปัญหาในการหยุดการเชื่อมต่อและเริ่มการเชื่อมต่อใหม่ ตัวอย่างเช่นสมมติว่าระบบรีโมตมีไฟร์วอลล์ที่ตามกำหนดการ คุณได้รับอนุญาตให้เชื่อมต่อเมื่อคุณทำและการเชื่อมต่อที่สร้างขึ้นไม่ได้ถูกปิด แต่ในเวลาปัจจุบันการเชื่อมต่อใหม่จะไม่ได้รับการยอมรับ
คุณทำสิ่งที่คุณต้องการแล้วและคุณพร้อมที่จะออกจากระบบแล้ว Bob เพื่อนของคุณอยู่ในห้องกับคุณและเขาต้องการทำงานกับระบบระยะไกล - แต่เขาจะไม่สามารถเชื่อมต่อได้ ดังนั้นคุณพิมพ์exec su - bob
และเมื่อพรอมต์รหัสผ่านปรากฏให้เปลี่ยนเวิร์กสเตชันไปหาเขา ขณะนี้ไม่มีโพรซีเดอร์กับ UID ของคุณ (เว้นแต่คุณจะรันบางอย่างในพื้นหลัง) ดังนั้น Bob จะไม่สามารถยุ่งกับไฟล์ของคุณ เขาจะเข้าควบคุมการเชื่อมต่อของคุณอย่างมีประสิทธิภาพ (ด้วยความยินยอมและความร่วมมือจากคุณ)
หมายเหตุ:
su
หลักสูตรนี้จะไม่ทำงานถ้าคุณไม่ได้รับอนุญาตให้ทำงานwho
อาจจะยังคงแสดงชื่อของคุณ เป็นไปได้ว่าบางโปรแกรม (เขียนไม่ดี) จะใช้สิ่งนั้นเพื่อคิดว่าบ็อบเป็นคุณและให้เขาเข้าถึงทรัพยากรของคุณ(a;b)
แล้วจะเหมือนกับ(a;exec b)
เชลล์ที่ปรับส้อมสำหรับคำสั่งสุดท้ายในเชลล์ย่อยให้เหมาะสม ยกเว้นเพียงคนเดียวที่ดูเหมือนจะเป็นและbash
mksh
การใช้exec
ช่วยรับประกันได้