ทุบตีรองรับการฟอร์กคล้ายกับส้อมของ C หรือไม่?


25

ฉันมีสคริปต์ที่ฉันต้องการแยกไว้ที่จุดหนึ่งเพื่อให้สคริปต์เดียวกันทำงานสองชุด

ตัวอย่างเช่นฉันต้องการสคริปต์ทุบตีต่อไปนี้:

echo $$
do_fork()
echo $$

หากสคริปต์ทุบตีนี้มีอยู่จริงผลลัพธ์ที่คาดหวังจะเป็น:

<ProcessA PID>
<ProcessB PID>
<ProcessA PID>

หรือ

<ProcessA PID>
<ProcessA PID>
<ProcessB PID>

มีบางอย่างที่ฉันสามารถแทนที่ "do_fork ()" เพื่อรับเอาต์พุตชนิดนี้หรือทำให้สคริปต์ทุบตีทำส้อม C-like ได้หรือไม่

คำตอบ:


23

ใช่. การสะกดเป็นทางแยก&:

echo child & echo parent

สิ่งที่อาจทำให้คุณสับสน$$คือไม่ใช่ PID ของกระบวนการเชลล์ แต่เป็น PID ของกระบวนการเชลล์ดั้งเดิม จุดที่ทำให้มันเป็นเช่นนี้คือ$$ตัวระบุที่ไม่ซ้ำกันสำหรับอินสแตนซ์เฉพาะของเชลล์สคริปต์: มันจะไม่เปลี่ยนแปลงในระหว่างการทำงานของสคริปต์และมันแตกต่างจาก$$สคริปต์อื่นที่รันพร้อมกัน sh -c 'echo $PPID'วิธีการหนึ่งที่จะได้รับกระบวนการของเปลือกที่เกิดขึ้นจริงเป็น PID

โฟลว์คอนโทรลในเชลล์ไม่เหมือนกับ C. หากใน C คุณต้องการเขียน

first(); fork(); second(); third();

ดังนั้นเปลือกที่เทียบเท่าคือ

after_fork () { second; third; }
first; after_fork & after_fork

รูปแบบเปลือกง่ายfirst; child & parentสอดคล้องกับสำนวน C ปกติ

first(); if (fork()) parent(); else child();

&และ$$มีอยู่และประพฤติเช่นนี้ในทุกเชลล์สไตล์ Bourne และใน (t) csh $PPIDไม่มีอยู่ในเชลล์ Bourne แบบดั้งเดิม แต่อยู่ใน POSIX (ดังนั้นจึงเป็นแบบ Ash, bash, ksh, zsh, …)


3
แต่โดยทั่วไปแล้วคือ "fork + exec" ไม่ใช่แค่ทางแยก
mattdm

@mattdm: เอ่อ? &คือ fork ไม่มีผู้บริหารที่เกี่ยวข้อง Fork + exec คือเมื่อคุณเรียกใช้คำสั่งภายนอก
Gilles 'ดังนั้น - หยุดความชั่วร้าย'

@mattdm: อ่าฉันคิดว่าฉันเห็นว่า Cory กำลังทำอะไรอยู่ ไม่มีexecแต่ทั้งสองภาษามีโฟลว์การควบคุมที่แตกต่างกัน
Gilles 'ดังนั้น - หยุดความชั่วร้าย'

1
@Gilles: ตัวดำเนินการควบคุม bash &เริ่ม subshell ซึ่งคำสั่งที่กำหนดจะถูกดำเนินการ ส้อม + ผู้บริหาร คุณไม่สามารถใส่&โดยไม่มีคำสั่งก่อนหน้าเพื่อดำเนินการ
mattdm

5
ถ้าคำว่า "Forking สะกด & &" เป็นคำพูดจริงคุณสามารถใส่&บรรทัดด้วยตัวเอง แต่คุณทำไม่ได้ มันไม่ได้แปลว่า "ส้อมนี่" มันหมายถึง "รันคำสั่งก่อนหน้านี้ในพื้นหลังใน subshell"
mattdm

10

ใช่มันเรียกว่าsubshells รหัสเชลล์ในวงเล็บถูกเรียกใช้เป็น subshell (fork) อย่างไรก็ตามโดยปกติเชลล์แรกจะรอให้ลูกดำเนินการตามปกติ คุณสามารถทำให้มันไม่ตรงกันโดยใช้&terminator เห็นมันในทางปฏิบัติกับบางสิ่งเช่นนี้:

#!/bin/bash

(sleep 2; echo "subsh 1")&
echo "topsh"

$ bash subsh.sh


5
วงเล็บสร้างเชลล์ย่อย แต่นั่นคือ fork + wait &เป็นคนเดียว หากคุณต้องการดำเนินการมากกว่าหนึ่งขั้นตอนในกระบวนการลูกก็เพียงพอที่จะใช้เครื่องมือจัดฟัน (ซึ่งดำเนินการจัดกลุ่มโดยไม่ต้องสร้างกระบวนการเด็ก):{ sleep 2; echo child; } &
Gilles 'ดังนั้น - หยุดความชั่วร้าย'

6

ไม่มีวิธีการทุบตีพื้นเมือง มีหลายวิธีที่จะวางไข่กระบวนการที่แยกจากกันซึ่งทำสิ่งอื่นแบบอะซิงโครนัส แต่ฉันไม่คิดว่าจะมีอะไรที่ตามหลังความหมายที่แน่นอนของการเรียกระบบ fork ()

วิธีการทั่วไปคือให้สคริปต์ระดับสูงของคุณออกมาช่วยผู้ทำงานที่คุณต้องการแยกออก ถ้าคุณทำ$0 $@ &หรืออะไรก็ตามคุณจะเริ่มต้นใหม่อีกครั้งและต้องคิดออกก่อน

จริง ๆ แล้วฉันเริ่มคิดวิธีที่ฉลาดหลายวิธีที่หนึ่งอาจทำเช่นนั้น ....

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


2
แม้ว่าจุดของคุณเป็นไวยากรณ์ taken- ดีทุบตีเป็นเรื่องยากที่เนื้อหาและมันหายไปโครงสร้างข้อมูลสง่างามมากขึ้นและคุณสมบัติของ Perl หรืองูหลามทุบตีเป็นจริงมัน gets- ประสิทธิภาพสูง เป็นภาษาเฉพาะโดเมนและฉันจะโต้แย้งได้ดียิ่งขึ้น (รวบรัด, ง่ายกว่า) กว่าเช่น Python ในหลาย ๆ กรณี คุณสามารถจัดการระบบมากมายและไม่รู้จัก Python ได้หรือไม่? ใช่. คุณสามารถทำสิ่งนั้นและไม่รู้การทุบตี [โปรแกรม] หรือไม่? ฉันไม่อยากลอง หลังจาก 30 ปีของการเขียนโปรแกรมเชลล์ฉันบอกคุณว่ามันเป็นเรื่องจริงตามที่ได้รับ และใช่ฉันพูดงูใหญ่ แต่อย่าสับสนกับเด็ก ๆ
Mike S

2
ที่กล่าวว่าในทางเทคนิคฉันชอบคำตอบนี้มากขึ้น ในการพูดว่า "&" คือคำตอบสำหรับคำถามของผู้ใช้ "แยกมาถึงจุดหนึ่งดังนั้นสคริปต์ที่เหมือนกันสองชุดที่ทำงานอยู่" คือความคิดของฉันที่ทำให้สับสน สิ่งที่ "&" ทำตามคู่มือทุบตีคือ "... ดำเนินการคำสั่ง [ที่กำหนด] ในพื้นหลังใน subshell" จะต้องยุติคำสั่งและเกี่ยวข้องกับ fork (ในทางเทคนิคใน Linux, clone ()) แต่ ณ จุดนั้นสำเนาสองชุดของสคริปต์เดียวกันไม่ได้ทำงาน
Mike S
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.