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


19

สมมติว่าฉันมีสาม (หรือมากกว่า) สคริปต์ทุบตี: script1.sh, และscript2.sh script3.shผมอยากจะเรียกทั้งสามของสคริปต์เหล่านี้และเรียกพวกเขาในแบบคู่ขนาน วิธีหนึ่งในการทำเช่นนี้คือเพียงเรียกใช้คำสั่งต่อไปนี้

nohup bash script1.sh &
nohup bash script2.sh &
nohup bash script3.sh &

(โดยทั่วไปสคริปต์อาจใช้เวลาหลายชั่วโมงหรือหลายวันจึงจะเสร็จสิ้นดังนั้นฉันต้องการใช้nohupเพื่อให้สคริปต์ทำงานต่อไปแม้ว่าคอนโซลของฉันจะปิด)

แต่มีวิธีใดบ้างที่จะดำเนินการคำสั่งทั้งสามนี้ควบคู่กับการโทรครั้งเดียว ?

ฉันกำลังคิดอะไรบางอย่างเช่น

nohup bash script{1..3}.sh &

แต่นี้จะปรากฏในการดำเนินการscript1.sh, script2.shและscript3.shในลำดับที่ไม่ได้อยู่ในแบบคู่ขนาน


2
"การโทรครั้งเดียว" หมายความว่าอะไร?
jw013

1
กรณีการใช้งานคืออะไร? คุณมีสคริปต์นับล้านที่จะเริ่มหรือไม่
l0b0

@ jw013 ฉันหมายถึงบางคำสั่งเหมือนกับบรรทัดคำสั่งสั้น ๆ หากฉันมี 100 สคริปต์ที่จะเริ่มต้นฉันต้องการที่จะพิมพ์บางสิ่งบางอย่างสั้น ๆ (เช่นnohup bash script{1..100}.sh &หรือfor i in {1..100}; do nohup bash script{1..100} &; done) แทนที่จะพิมพ์nohup bash script*.sh &100 ครั้งที่แตกต่างกัน
แอนดรู

1
ในกรณีที่สคริปต์มีเอาต์พุตที่มีประโยชน์: คุณสามารถเริ่มสคริปต์ภายในscreenได้เช่นกัน (หรือtmux) เพื่อแก้ปัญหาคอนโซล แต่ให้เข้าถึงเอาต์พุต (และอินพุต)
Hauke ​​Laging

1
ไม่มีสิ่งใดที่ป้องกันไม่ให้คุณพิมพ์ทั้ง 3 คำสั่งเหล่านั้นในบรรทัดเดียวกัน nohup ... & nohup ... & nohup ... &. หากคุณหมายถึงว่าคุณต้องการเรียกใช้สคริปต์ทั้งหมดโดยไม่ต้องพิมพ์ชื่อสคริปต์แต่ละชื่อการวนซ้ำอย่างง่ายจะทำ
jw013

คำตอบ:



14

วิธีที่ดีกว่าที่จะใช้GNU ขนาน GNU Parallel นั้นง่ายและเราสามารถควบคุมจำนวนงานเพื่อให้ทำงานแบบขนานพร้อมกับควบคุมงานได้มากขึ้น

ในคำสั่งด้านล่างscript{1..3}.shได้รับการขยายและถูกส่งเป็นอาร์กิวเมนต์ไปbashในแบบคู่ขนาน ที่นี่-j0บ่งชี้ว่ามีงานมากที่ควรถูกเรียกใช้มากที่สุด โดยค่าเริ่มต้นparallelทำงานหนึ่งงานสำหรับหนึ่งซีพียูคอร์

$ parallel -j0 bash :::: <(ls script{1..3}.sh)

และคุณยังสามารถลองใช้

$ parallel -j0 bash ::: script{1..3}.sh

ในขณะที่ดำเนินการวิธีที่สองถ้าคุณได้รับข้อความแสดงข้อผิดพลาดใด ๆ ก็หมายความว่า--tollefตัวเลือกที่มีการตั้งค่า/etc/parallel/configและที่จะต้องถูกลบและทุกสิ่งจะทำงานได้ดี

คุณสามารถอ่านGNU Parallelsman page ได้ที่นี่เพื่อดูตัวเลือกที่สมบูรณ์ยิ่งขึ้น

และในกรณีที่หากคุณกำลังเรียกใช้งานจากเครื่องระยะไกลควรใช้งานscreenให้ดีขึ้นเพื่อไม่ให้เซสชันถูกปิดเนื่องจากปัญหาเครือข่าย nohupไม่จำเป็นต้องเป็นรุ่นล่าสุดของทุบตีเป็นที่มาพร้อมกับhuponexitเป็นoffและนี้จะป้องกันไม่ให้เปลือกปกครองจากการส่งHUPสัญญาณให้กับเด็กในช่วงทางออกของมัน ในกรณีที่ไม่ได้ทำการตั้งค่าไว้

$ shopt -u huponexit  

หากคุณจะใช้bashเป็นเชลล์parallel -j0 bash :::: <(ls script{1..3}.sh)สามารถลดเป็นparallel -j0 bash :::: script{1..3}.shใช่หรือไม่?
iruvar

ไม่มันไม่ใช่เมื่อใช้ '::::' กับขนานมันหมายความว่าอาร์กิวเมนต์เป็นไฟล์ที่มีคำสั่งที่จะดำเนินการและไม่คำสั่งเอง ที่นี่เรากำลังใช้การทดแทนกระบวนการเพื่อเปลี่ยนเส้นทางชื่อสคริปต์ภายในไฟล์อธิบาย
Kannan Mohan

เอ่อ .. ในกรณีนั้นทำไมparallel -j0 bash ::: script{1..3}.shล่ะ?
iruvar

มันbash ::: script{1..3}.shจะถูกส่งผ่านไปยังไม่parallel ::: script{1..3}.shดังนั้นนี้เป็นครั้งแรกควรจะขยายตัวออกไป parallel bash ::: script1.sh script2.sh script3.shโดยเปลือกแล้วparallelสวดของbash script1.sh, ,bash script2.sh bash script3.shฉันลองแล้ว
iruvar

1
ไม่ฉันไม่สับสนสิ่งที่ฉันระบุคือปัญหาของ OP ดีขึ้นด้วยparallel -j0 bash ::: script{1..3}.sh- นี่ดีกว่า::::วิธีเนื่องจากไม่ต้องเปลี่ยนกระบวนการ นอกจากนี้การแยกวิเคราะห์ ls output จะถูกขี่ด้วย
หลุม

9

นอกจากนี้เรายังสามารถใช้xargsเพื่อเรียกใช้สคริปต์หลายตัวพร้อมกัน

$ ls script{1..5}.sh|xargs -n 1 -P 0 bash

ที่นี่แต่ละสคริปต์ถูกส่งผ่านไปยัง bash เป็นอาร์กิวเมนต์แยกกัน -P 0บ่งชี้ว่าจำนวนกระบวนการแบบขนานสามารถมากที่สุด job control feature (&)นอกจากนี้ยังมีความปลอดภัยมากขึ้นว่าการใช้ค่าเริ่มต้นทุบตี


5

โซลูชันบรรทัดเดียว:

$ nohup bash script1.sh & nohup bash script2.sh & nohup bash script3.sh &

ไม่ค่อยน่าสนใจเพียงใช้สคริปต์ wrapper:

$ cat script.sh
#!/usr/bin/env bash
script1.sh &
script2.sh &
script3.sh &
$ nohup script.sh &

หรือวนรอบพวกเขา:

for script in dir/*.sh
do
    nohup bash "$script" &
done

2

หากคุณกำลังมองหาการประหยัดการพิมพ์

eval "nohup bash "script{1..3}.sh" &"

หรือในความคิดที่สองอาจจะไม่


1

ชำระเงินเครื่องมือนี้: https://github.com/wagoodman/bashful

สมมติว่าคุณมีmytasks.yamlกับ

tasks:
    - name: A title for some tasks
      parallel-tasks:
        - cmd: ./script1.sh
        - cmd: ./script2.sh -x an-arg
        - cmd: ./script3.sh -y some-other-arg

และคุณเรียกใช้เช่น:

nohup bashful run mytasks.yaml

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

config:
    max-parallel-commands: 6
tasks:
    ...

คำเตือน: ฉันเป็นผู้เขียน


0

ฉันแนะนำโปรแกรมอรรถประโยชน์ที่ง่ายกว่ามากที่ฉันเพิ่งเขียน ปัจจุบันเรียกว่า par แต่จะเปลี่ยนชื่อเป็น parl หรือ pll ในไม่ช้ายังไม่ได้ตัดสินใจ

https://github.com/k-bx/par

API นั้นง่ายเหมือน:

par "script1.sh" "script2.sh" "script3.sh"

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