ทำไมฟังก์ชั่นจะไม่กลับมาจนกว่ากระบวนการพื้นหลังจะสิ้นสุด


21

พิจารณาสคริปต์นี้:

#!/bin/bash
function start {
  leafpad &
  echo $!
}
PID=$(start)
echo "PID is $PID"

สคริปต์ไม่ดำเนินการผ่านวงเล็บปีกกาปิดจนกว่ากระบวนการ leafpad จะสิ้นสุดลงแม้ว่าจะเป็นกระบวนการพื้นหลัง

ทำไมนี้ เป็นไปได้หรือไม่ที่จะเริ่มกระบวนการพื้นหลังจากฟังก์ชั่น?

คำตอบ:


22

ฟังก์ชันส่งคืน แต่บล็อกการแทนคำสั่งเนื่องจากคุณสร้างงานพื้นหลัง แต่คุณยังคงเปิด stdout fd ไว้ เพียงแค่ปิดได้โดยการเพิ่มก่อน>/dev/null&

#!/bin/bash
function start {
  leafpad >/dev/null &
  echo $!
}
PID=$(start)
echo "PID is $PID"

หากคุณต้องการให้กระบวนการของคุณปิด stdin, stdout, stderr ด้วยให้ใช้สิ่งนี้:

leafpad >/dev/null 0>&1 2>&1 &

สิ่งนี้จะปิด stdin (0), stdout (1) และ stderr (2) จากนั้นพื้นหลัง (&) นอกจากนี้เมื่อใช้การเปลี่ยนเส้นทางสตรีมอย่าลืมว่า "ซ้ำซ้อน" นั่นหมายถึงการทำซ้ำตามลำดับของการดำเนินการ

1>/dev/null 2>&1

และ

2>&1 1>/dev/null

ไม่เหมือนกัน! ในอดีตคุณกำลังทำซ้ำสตรีมไปยัง / dev / null (ซึ่งเป็นสิ่งที่คุณต้องการ) ในภายหลังคุณจะทำซ้ำ / dev / stdout เป็น stderr แล้วปิด stdout ดังนั้นข้อความใดก็ตามที่ส่งไปยังstderrจะปรากฏในคอนโซลของคุณ


ยืนยันในระบบของฉัน
user120161

10
คุณไม่ได้ปิดสตรีมคุณกำลังเปลี่ยนเส้นทาง
dcat

4
ใกล้; n>&-โดยที่nfile descriptor อยู่ที่ไหน
dcat

1
@dcat: ใช่ แต่การเปลี่ยนเส้นทางไปยัง / จาก/dev/nullจะไม่นำไปสู่ข้อผิดพลาด i / o เมื่อกระบวนการพยายามเขียน stdout แต่พบว่า1FD นั้นไม่ถูกต้อง ดังนั้นคำศัพท์ในการโพสต์จึงไม่ใช่การเขียนโปรแกรมทุบตีจริง (ที่จริงแล้วการทำซ้ำ FD 1 ถึง 0 หมายความว่า stdin จะเป็น file-descriptor ที่เปิดด้วยO_RDONLYซึ่งอาจจะทำให้เกิดข้อผิดพลาด (แทนที่จะเป็นแบบไม่มีไบต์ที่ต้องการ) เมื่อกระบวนการพยายามอ่าน) เช่นwc >/dev/null 0>&1->wc: standard input: Bad file descriptor
Peter Cordes

1
@PeterCordes - การปิดตัวแสดงรายละเอียดเก่าและการเปลี่ยนเส้นทางตัวใหม่นั้นไม่จำเป็นต้องเกิดขึ้นพร้อมกัน exec <&- >&- <>/dev/null >&0จัดการ stdin / out สวยอย่างละเอียดถี่ถ้วน มันทำให้เกิดความแตกต่างในzshอย่างน้อยซึ่งจะเรียงลำดับของการเชื่อมทั้งหมดเปิดใน descriptor เดียวกันโดยอัตโนมัติเมื่อตั้งค่ามัลติ
mikeserv
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.