ฉันจะเรียกใช้คำสั่งพื้นหลังหลายคำในทุบตีในบรรทัดเดียวได้อย่างไร


169

ปกติฉันจะใช้คำสั่งหลาย ๆ อย่างเช่น:

sleep 2 && sleep 3

หรือ

sleep 2 ; sleep 3

แต่ถ้าฉันต้องการเรียกใช้ทั้งสองในพื้นหลังจากคำสั่งบรรทัดคำสั่งเดียว?

sleep 2 & && sleep 3 &

ไม่ทำงาน และไม่แทนที่&&ด้วย;

มีวิธีทำหรือไม่?


8
ใช้()เพื่อล้อมรอบคำสั่ง
nhahtdh

คำตอบ:


319

คุณต้องการให้พวกเขาทำงานได้อย่างไร หากคุณต้องการให้เริ่มทำงานในพื้นหลังและทำงานตามลำดับคุณจะทำสิ่งนี้:

(sleep 2; sleep 3) &

ในทางกลับกันหากคุณต้องการให้พวกเขาทำงานแบบขนานในพื้นหลังคุณสามารถทำสิ่งนี้แทน:

sleep 2 & sleep 3 &

และทั้งสองเทคนิคสามารถรวมกันได้เช่น:

(sleep 2; echo first finished) & (sleep 3; echo second finished) &

ทุบตีการทุบตีมักจะมีเทคนิคที่แตกต่างกันมากมายในการทำงานเดียวกันแม้ว่าบางครั้งจะมีความแตกต่างกันเล็กน้อยระหว่างพวกเขา


20
นี่เป็นคำตอบที่กระชับและคิดออกมาอย่างดีว่า "สอนให้คนหาปลา" เพื่อชีวิต ขอบคุณ
ambrus

2
จะเกิดอะไรขึ้นถ้าเราทำsleep 2 && sleep 3 &? ฉันพยายามทุบตีและดูเหมือนว่าจะทำงานในลักษณะเดียวกัน (ลองใช้กับเสียงสะท้อน)
Wajahat

@HakanBaba ใช่มันสร้าง subshell ในพื้นหลังแน่นอน
Douwe van der Leest

3
@Wajahat คุณลองsleep 2 && echo "foo" && sleep 3 & echo "bar""หรือยัง &&ผู้ประกอบการบอกเปลือกดำเนินการคำสั่งก่อนที่มันและเฉพาะในกรณีที่รันคำสั่งไม่มีข้อผิดพลาดใด ๆ เปลือกรันคำสั่งที่ตามมา สิ่งนี้แตกต่างอย่าง;มากเนื่องจาก;ให้คำสั่งที่ตามมาดำเนินการโดยไม่คำนึงถึงสถานะการออกของคำสั่งก่อนหน้ายกเว้นว่าเป็นข้อผิดพลาดร้ายแรง คำสั่ง&บอกเชลล์ให้ดำเนินการคำสั่ง "เชื่อมต่อ" ทั้งหมดที่อยู่ข้างหน้าในพื้นหลัง "เชื่อมต่อ" ที่นี่หมายถึงคำสั่งเป็นส่วนหนึ่งของไปป์ ( |) หรือตัวดำเนินการเชิงตรรกะ
Douwe van der Leest

Of these list operators, ‘&&’ and ‘||’ have equal precedence, followed by ‘;’ and ‘&’, which have equal precedence.ในคู่มือทุบตี
jinbeom hong

49

คุณต้องเพิ่ม parens ในเวอร์ชั่นล่าสุดของคุณ -

(sleep 2 &) && (sleep 3 &)

หรือยังใช้งานได้ -

(sleep 2 &) ; (sleep 3 &)

หมายเหตุ: เมื่อใช้รายการกับ&สถานะการออกรายการนั้นจะเป็นศูนย์เสมอ ดังนั้นทั้งสองกรณีข้างต้นทำสิ่งเดียวกัน (เชลล์ดำเนินการทั้งสองด้านในแบบอะซิงโครนัส )
jinbeom hong

9

ในการเรียกใช้คำสั่งพื้นหลังหลายคำคุณต้องเพิ่ม&จุดสิ้นสุดของแต่ละคำสั่ง อดีต: (command1 &) && (command2 &) && (command3 &)


5

คำตอบข้างต้นใช้วงเล็บ Bash สามารถใช้เครื่องมือจัดฟันเพื่อจุดประสงค์ที่คล้ายกัน:

{ sleep 2 && sleep 3; } &

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


1
เกี่ยวกับ{ sleep 2; sleep 3; } &อะไร
Kenny Evitt


0

ฉันมีภารกิจเดียวกันด้วย ฉันลอง(sleep2 ; fg )& sleep3 ; fgแล้วมันใช้งานได้ และเมื่อคุณประกาศล่วงหน้า ctrl + c เป็นสองเท่ากระบวนการทั้งสองสามารถหยุดทำงานได้


0

คุณสามารถใช้การทดแทนคำสั่ง bash $(command)ดังนี้:

$(command1 ; command2) &

โปรดทราบว่า stdin และ stdout ยังคงเชื่อมโยงกับกระบวนการหลักและการเปลี่ยนเส้นทางอย่างน้อย stdout อาจเป็นเรื่องยุ่งยาก ดังนั้นคุณสามารถโยงคำสั่งในหนึ่งบรรทัดแล้วส่งสตริงไปยังbashคำสั่งเพื่อวางไข่กระบวนการใหม่ซึ่งจะจัดการการดำเนินการ

bash -c "command1 ; command2" & 

สิ่งนี้มีประโยชน์อย่างยิ่งในสคริปต์ทุบตีเมื่อคุณต้องการเรียกใช้หลายคำสั่งในพื้นหลัง

ข้อความทั้งสองนี้ควรเทียบเท่ากัน ทุบตีกระบวนการวางไข่ในทั้งสองกรณีที่จะจัดการกับคำสั่ง (โซ่ของคำสั่ง) และ&ในตอนท้ายแยกการดำเนินการ

เวลานี้คุณสามารถเพิ่ม&>/dev/nullก่อนหน้า&ในตอนท้ายของคำสั่งเพื่อเปลี่ยนเส้นทางอย่างน้อย stdout และหลีกเลี่ยงเอาต์พุตบน stdout ของกระบวนการพาเรนต์ สิ่งที่ต้องการ:

bash -c "command1 ; command2" &>/dev/null &

-1

หากคุณต้องการเรียกใช้หลายคำสั่งตามลำดับมีวิธีง่าย ๆ ที่ทำงานได้ทุกที่: การสร้างไฟล์! ประโยชน์ของวิธีนี้คือมันสะอาดและเรียบง่าย

commands.shขั้นแรกให้สร้างไฟล์ของคุณที่มีชื่อเช่น จากนั้นใส่คำสั่งของคุณที่นั่น นี่คือตัวอย่าง:

commands.sh:

#!/system/bin/sh

sleep 3;
sleep 2;

ตกลงตอนนี้เรากำลังอยู่ในขั้นตอนสุดท้าย ในการรันคำสั่งในพื้นหลัง (เรียงตามลำดับ) เพียงแค่เรียกใช้:

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