เรียกใช้สคริปต์ Bash ในโฟลเดอร์ทั้งหมดในเวลาเดียวกัน


10

สมมติว่าฉันมี.shสคริปต์Bash ( ) ห้าตัวในโฟลเดอร์ ( my_folder) และมีชื่อดังนี้:

script_1.sh
script_2.sh
script_3.sh
script_4.sh
script_5.sh

ฉันจะเขียนสคริปต์ Bash ที่หกหรือเพียงหนึ่งซับที่จะเริ่มทำงานสคริปต์เหล่านี้ด้วยกันได้อย่างไร

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


คำตอบ:


12

GNU parallelนั้นสมบูรณ์แบบสำหรับสิ่งนี้ ติดตั้งด้วยsudo apt install parallelแล้ว:

parallel -j0 ::: my_folder/*sh

การ-jควบคุมจำนวนกระบวนการที่ทำงานแบบขนานและ-j0หมายถึง "กระบวนการทั้งหมด" ตั้งเป็นค่าอื่น (เช่น-j20) เพื่อเรียกใช้สคริปต์ในแบตช์แทน


1
หมายเหตุ: นอกจากนี้ยังมีparallelคำสั่งจากmoreutilsแพคเกจ การใช้งานตัวอย่างเช่นparallel -j 20 -- my_folder/*.sh(ซึ่งแตกต่างจาก GNU parallel, -j0จะวิ่งหนึ่งสคริปต์ในเวลา)
jfs

1
@jfs เป็นจุดที่ดี แต่โปรดทราบว่าsudo apt install parallelจะแทนที่ไฟล์/usr/bin/parallelด้วยไฟล์จาก GNU ขนาน ดังนั้นตราบใดที่คุณติดตั้งตามคำแนะนำของฉันมันควรจะทำงานได้ตามที่คาดไว้
terdon

ใช่ฉันพบว่ามันเป็นวิธีที่ยากเมื่อพยายามใช้parallelคำสั่งไม่สำเร็จจากคู่มือในขณะที่เขียนคำตอบของฉันเพื่อแนะนำ GNU ขนาน
jfs

9

หากต้องการเรียกใช้สคริปต์ทั้งหมดในเวลาเดียวกัน (ขนาน) ให้ใช้:

script_1.sh &
script_2.sh &
script_3.sh &
script_4.sh &
script_5.sh &

หากต้องการเรียกใช้งานหลังจากการใช้งานแบบอื่น ๆ (เรียงตามลำดับ):

script_1.sh &&
script_2.sh &&
script_3.sh &&
script_4.sh &&
script_5.sh

การปรับปรุงสำหรับความคิดเห็น

หากคุณมี 200 สคริปต์ที่คุณต้องการเรียกใช้ในเวลาเดียวกัน (ซึ่งอาจทำให้เครื่อง BTW ล้มเหลว) ให้ใช้สคริปต์นี้:

#!/bin/bash
for Script in my_folder/*.sh ; do
    echo bash "$Script" &
done

ตั้งค่าแอ็ตทริบิวต์สคริปต์ให้สามารถเรียกทำงานได้ด้วยคำสั่ง:

chmod a+x /path/to/script.sh

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

    echo bash "$Script" &

ถึง:

    bash "$Script" &

มีสามวิธีในการเรียกสคริปต์ทุบตีจากอีกวิธีหนึ่งดังนี้:

  1. ทำให้สคริปต์อื่นสามารถทำงานได้เพิ่ม#!/bin/bashบรรทัดที่ด้านบนและพา ธ ที่ไฟล์อยู่ใน$PATHตัวแปรสภาพแวดล้อม จากนั้นคุณสามารถเรียกมันเป็นคำสั่งปกติ

  2. หรือเรียกมันด้วยคำสั่ง source (นามแฝงคือ.) เช่นนี้: source /path/to/script;

  3. หรือใช้คำสั่ง bash เพื่อดำเนินการ: /bin/bash /path/to/script;

ในกรณีของ OP หนึ่งหรือมากกว่าหนึ่งใน 200 สคริปต์ไม่ได้มี#!/bin/bashบรรทัดแรกShebang ในไฟล์ เช่นตัวเลือก 3. จะต้องมีการใช้


200 สคริปต์ทำงานในเวลาเดียวกัน

มีการยกความคิดเห็นเกี่ยวกับว่า "กำลังทำงานในเวลาเดียวกัน" หรือไม่ ในระบบซีพียูทั่วไป 8 ตัว 25 สคริปท์จะแชร์ซีพียูหนึ่งตัวในเวลาเดียวกัน แต่จะมีสคริปท์เพียงหนึ่งตัวที่จะดำเนินการในแต่ละครั้งจนกว่าจะถึงเวลาแบ่ง (วัดเป็นมิลลิวินาที) จากนั้นงานต่อไปจะได้รับส่วนแบ่งอย่างยุติธรรมเป็นมิลลิวินาทีจากนั้นงานต่อไป ฯลฯ และอื่น ๆ

ในแง่หลวมเราสามารถพูดได้ว่า 200 งานกำลังทำงาน "พร้อมกัน" แต่ไม่ใช่ "พร้อมกัน" ใน 8 ซีพียูซึ่งเท่ากับ 25 งานต่อซีพียู:

ด้ายสถานะ. png

ภาพด้านบนและความคิดเห็นด้านล่างจากตัวจัดกำหนดการเคอร์เนล Linux

time slice.png


ขอบคุณ .. สิ่งที่เป็นจริงในกรณีของฉันฉันมีสคริปต์มากกว่า 200 สคริปต์ให้ทำงาน มีวิธีใดบ้างที่ฉันสามารถรันคำสั่งทั้งหมดด้วยคำสั่งเดียว (เช่นโดยไม่ต้องเขียนชื่อไฟล์)
aaaaa

@aaaaa ฉันได้เปลี่ยนคำตอบสำหรับ 200 สคริปต์
WinEunuuchs2Unix

ขอบคุณ มันได้ผล .. สิ่งเดียวที่ฉันต้องเพิ่มในบรรทัดสุดท้ายของคุณคือ 'ทุบตี' ไม่เช่นนั้นฉันจะได้รับ 'ปฏิเสธการอนุญาต'
aaaaa

1
@aaaaa คุณต้องการให้สคริปต์มากกว่า 200 สคริปต์ทำงานพร้อมกันหรือคุณต้องการให้มีจำนวนน้อยลง (พูดว่า 10) เรียกใช้พร้อมกันโดยที่คนอื่น ๆ เข้าคิวเพื่อทำงานเมื่อสคริปต์หนึ่งหรือมากกว่าทำเสร็จและ จำนวนสคริปต์ที่กำลังทำงานอยู่ลดลงต่ำกว่าจำนวนนั้นหรือไม่ (หากคุณสนใจโซลูชันดังกล่าวฉันขอแนะนำให้แก้ไขคำถามของคุณด้วยข้อมูลเกี่ยวกับจำนวนสคริปต์ที่คุณมีระยะเวลาที่ต้องใช้ในการทำงานประเภทใดที่พวกเขาทำและอื่น ๆ )
Eliah Kagan

@aaaaa ขอบคุณสำหรับความคิดเห็น ฉันได้อัปเดตคำตอบเพื่อรวมbashคำนำหน้าเพื่อเรียกใช้สคริปต์
WinEunuuchs2Unix

3

มีเครื่องมือสำหรับอ่านman run-partsนี้

ตัวอย่างเช่นฉัน:

 run-parts ${visorhome}/pbackup.d/

ในสคริปต์สำรองข้อมูล Palm Pilot ของฉัน ${visorhome}/pbackup.d/:

01PopulateJpilot  02Extract_Pedometer  03URLs  04google  05Books  06Weight  07Sec  08Bkgm 50hardlinks

1
@ eliah-kagan กำลังเรียกใช้ "สคริปต์มากกว่า 200 ตัว" "ในเวลาเดียวกัน" ดูเหมือนไม่ฉลาด มันอาจจะเป็นวิธีที่ดีในการทดสอบระบบความเครียด
waltinator

จุดดี. ฉันคิดว่าคุณยังอาจต้องการพูดถึงว่าrun-partsรันสคริปต์ตามลำดับแทนที่จะเป็นทั้งหมดในครั้งเดียวตามที่ OP ร้องขอ แม้ว่าคุณจะถูกต้องการเรียกใช้สคริปต์ 200 สคริปต์ในครั้งเดียวนั้นไม่น่าจะเหมือนกับการใช้งาน 5 - และแม้ว่าการเรียกใช้สคริปต์ทั้งหมดในครั้งเดียวจะไม่ทำให้เกิดปัญหาใด ๆ แต่ก็อาจไม่จำเป็น ฉันได้แสดงความคิดเห็นเพื่อแนะนำ OP ชี้แจงการตั้งค่าของพวกเขาในเรื่องนี้
Eliah Kagan

run-partsจะไม่เรียกใช้สคริปต์ (มีจุดในชื่อ:my_folder/*.sh
jfs

1
run-partsมี ข้อกำหนดเฉพาะชื่อไฟล์ที่เฉพาะเจาะจงด้วยเหตุผลแปลก ๆ มันจะไม่เปิดชื่อไฟล์ที่มีนามสกุลดังนั้นฉันเกรงว่าจะไม่ทำงานที่นี่
terdon

1

วิธีรัน*.shสคริปต์ทั้งหมดในmy_folderไดเรกทอรีพร้อมกันโดยใช้xargs:

$ ls my_folder/*.sh | xargs -P0 -n1 bash

หากต้องการ จำกัด จำนวนสคริปต์ที่เรียกใช้งานพร้อมกัน10:

$ ls my_folder/*.sh | xargs -P10 -n1 bash

เป็นวิธีปฏิบัติที่ไม่ดีที่จะใช้ผลลัพธ์lsในสคริปต์ การใช้findปลอดภัยกว่ามาก มันเป็นรายการแรกที่นี่: mywiki.wooledge.org/BashPitfalls#for_f_in_.24.28ls_.2A.mp3.29
Joe

@ โจโดยทั่วไปมันเป็นเรื่องจริง ฉันไม่เห็นปัญหาในกรณีนี้
jfs

นั่นเป็นเพราะคุณรู้แล้วเกี่ยวกับมัน คนที่มาที่นี่ในภายหลังอาจไม่ได้
Joe

@Joe ไม่ติดตาม dogma สุ่มสี่สุ่มห้า คิดว่าด้วยตัวคุณเองมากกว่าตัวเลือกหนึ่งจะดีกว่าอีกทางเลือกหนึ่งสิ่งที่ไม่ชอบในกรณีของคุณ
jfs

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