ฉันจะเรียกใช้หลายคำสั่งที่มี & ในหนึ่งบรรทัดคำสั่งได้อย่างไร


12

ฉันพบปัญหาปวดหัว

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

myCommand &

นอกจากนี้ยังง่ายต่อการเริ่มหลายคำสั่งเช่นนี้

myCommand1 && myCommand2

หรือ

myCommand1 ; myCommand2

แต่ถ้าฉันต้องการเรียกใช้หลายคำสั่งในพื้นหลังฉันลองรูปแบบคำสั่งต่อไปนี้ แต่ล้มเหลว:

myCommand1 & && myCommand2 &

หรือ

myCommand1 & ; myCommand2 &

รูปแบบทั้งสองล้มเหลว ฉันจะรันหลายคำสั่งที่มี&ในหนึ่งบรรทัดคำสั่งได้อย่างไร


2
วางไว้ในสคริปต์และเรียกใช้สคริปต์ในพื้นหลัง
Panther



Panther ดูเหมือนว่าการใช้ () สามารถช่วยแก้ไขปัญหานี้ได้ง่ายกว่าการใช้สคริปต์ เรามาลองใช้ประโยชน์จากคุณสมบัติต่าง ๆ ที่เชลล์จัดเตรียมไว้ก่อนก่อนแทนที่จะเขียนสิ่งที่เราต้องการด้วยตัวเอง แต่แน่นอนว่าการใช้สคริปต์สามารถแก้ไขปัญหานี้ได้เช่นกัน ขอบคุณอยู่ดี
นาฬิกา ZHONG

ถ้าฉันต้องการเรียกใช้ 'tail -F <file1>> <file2>' ตามด้วย 'jobs -l' ซึ่งตามมาอีกครั้งด้วย '
disown

คำตอบ:


24

ใช้ ()

หากคุณต้องการเรียกใช้ตามลำดับ:

(myCommand1; myCommand2) &

หรือ

(myCommand1 &) && (myCommand2 &)

หากคุณต้องการให้พวกเขาทำงานแบบขนาน:

myCommand1 & myCommand2 &

ในทุบตีคุณยังสามารถใช้ (ช่องว่างด้านหลัง {และ; จำเป็น;):

{ myCommand1 && myCommand2; } &

3
(myCommand1 &) && (myCommand2 &)จะทำงานmyCommand2แม้ว่าจะmyCommand1ล้มเหลว
terdon

() สามารถช่วย bash เพื่อแยกแยะความแตกต่างระหว่าง & & & ดังนั้นเพียงแค่ใช้ () เพื่อแยกหน่วยดำเนินการเมื่อเราต้องการใช้ & & & & togather
นาฬิกา ZHONG

16

ฉันคิดว่าคุณต้องการสิ่งนี้:

myCommand1 & myCommand2 &

สิ่งนี้เริ่มต้นmyCommand1และส่งไปที่พื้นหลังตามด้วยเครื่องหมายแอมเปอร์แซนด์จากนั้นเริ่มmyCommand2และส่งสิ่งนี้ไปยังพื้นหลังทันทีดังนั้นจึงปล่อยเชลล์อีกครั้ง

รายการ

เพื่อความเข้าใจที่ดีขึ้นคุณสามารถแทนที่ไปป์ไลน์ตามคำสั่งที่นี่

รายการคือลำดับของหนึ่งหรือมากกว่าหนึ่งท่อคั่นด้วยหนึ่งในผู้ประกอบการ; , & , &&หรือหรือ|| และถูกยกเลิกโดยหนึ่งใน ; , & , หรือ .

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

รายการ AND และ OR เป็นลำดับของหนึ่งหรือมากกว่าหนึ่งท่อคั่นด้วย && และ || ผู้ประกอบการควบคุมตามลำดับ
ที่มา:man bash

ลองแบ่งมันออกเป็นตัวอย่าง คุณสามารถสร้างรายการโดยรวมคำสั่งและแยกรายการเหล่านี้ด้วย; & && ||:

command1 ; command2  # runs sequentially
command1 && command2 # runs sequentially, runs command2 only if command1 succeeds
command1 || command2 # runs sequentially, runs command2 only if command1 fails
command1 & command2  # runs simultaneously

; & <newline>คุณสามารถบอกเลิกรายการกับหนึ่งเหล่านี้:
ปกติคุณรันคำสั่งหรือรายการโดยการกดที่เท่าเทียมกันEnter <newline>อัฒภาค;ทำหน้าที่จุดประสงค์เดียวกันโดยเฉพาะอย่างยิ่งในสคริปต์ เครื่องหมายแอมเปอร์แซนด์&เริ่มคำสั่งในเชลล์ย่อยในพื้นหลังปล่อยเชลล์ทันที

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

# if c1 succeeds start a shell in the background
# and run c2 and c3 sequentially inside it
c1 && ( c2 ; c3 ) & 
# run c1 and if it succeeds c2 sequentially as a group command
# if c1 or c2 fail run c3 in the background
{ c1 && c2 ;} || c3 &

สิ่งนี้อาจซับซ้อนมากหากคุณไม่แน่ใจในการใช้งานtrueและfalseเพื่อทดสอบว่างานก่อสร้างเป็นไปตามที่คาดไว้หรือไม่:

$ { true && true ;} || echo 2
$ { true && false ;} || echo 2
2

การควบคุมงาน

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

  • Ctrl+ Zพิมพ์อักขระsuspendที่ทำให้กระบวนการที่ทำงานอยู่ในเบื้องหน้าหยุดทำงานในขณะนั้นซึ่งจะไม่ถูกยกเลิก แต่ยังคงอยู่ในjobsรายการ
  • Ctrl+ Yพิมพ์อักขระsuspend ที่ล่าช้าซึ่งทำให้กระบวนการที่ทำงานอยู่ในเบื้องหน้าหยุดทำงานในขณะที่พยายามอ่านอินพุตจากเทอร์มินัล
  • fg= %นำกระบวนการเข้าสู่เบื้องหน้าเริ่มต้นหากจำเป็นคุณสามารถระบุกระบวนการดังต่อไปนี้:

     %       # last process in the jobs list
     %1      # 1st process in the jobs list
     %abc    # process beginning with the string “abc”
     %?abc   # process containing the string “abc” anywhere
  • bg= %&นำกระบวนการเข้าสู่พื้นหลังโดยเริ่มต้นหากจำเป็น:

     %&      # last process in the jobs list
     %1&     # 1st process in the jobs list
     %abc&   # process beginning with the string “abc”
     %?abc&  # process containing the string “abc” anywhere
  • wait รอให้กระบวนการพื้นหลังเสร็จสิ้นและส่งคืนสถานะการเลิกจ้าง:

     wait %1 # 1st process in the jobs list

    ลองนึกภาพคุณเริ่มกระบวนการที่มีความยาว ( jobsแสดงให้เห็นว่ามันเป็นหมายเลข 3) จากนั้นตระหนักว่าคุณต้องการให้คอมพิวเตอร์ถูกระงับเมื่อเสร็จสิ้นพร้อมechoข้อความถ้ากระบวนการไม่สำเร็จ:

     wait %3 || echo failed ; systemctl suspend

แต่สำคัญที่ต้องระวังด้วย && มันขึ้นอยู่กับสิ่งที่คำสั่งส่งคืนดังนั้นเราต้องแน่ใจว่าสิ่งที่เราเรียกจริง ๆ แล้วส่งคืนสิ่งที่ทุบตีถือว่าเป็นคุณค่าจริง .. ?
คณิตศาสตร์ที่

@Mathreadler ยกเว้นว่าคุณกำลังพูดถึงสคริปต์ผู้ใช้ที่ทำมาไม่ดีบางอย่างค่าออกจะถูกกำหนดไว้อย่างดี (ดูman bash) และใช้กันอย่างแพร่หลายตามที่ตั้งใจไว้ AFAIK - ฉันไม่เคยเจออะไรแปลก ๆ
ของหวาน

แน่นอนหนึ่งควรระมัดระวังเกี่ยวกับสคริปต์ผู้ใช้ทำไม่ดี พวกมันมีอยู่จริงและอาจเป็นความเจ็บปวดในการค้นหาข้อบกพร่องดังกล่าว Askubuntu ไม่อนุญาตให้ฉัน "@ dessert" คุณ
คณิตศาสตร์ที่

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