Chạy tất cả các tập lệnh Bash trong thư mục cùng một lúc


10

Giả sử tôi có năm .shtập lệnh Bash ( ) trong một thư mục ( my_folder) và chúng được đặt tên như sau:

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

Làm thế nào tôi có thể viết một tập lệnh Bash thứ sáu hoặc chỉ một tập lệnh sẽ bắt đầu chạy tất cả các tập lệnh này cùng nhau?

Tôi cần năm kịch bản để bắt đầu chạy tất cả cùng một lúc và không phải lần lượt từng tập lệnh.


Câu trả lời:


12

GNU parallellà hoàn hảo cho loại điều này. Cài đặt với sudo apt install parallelvà sau đó:

parallel -j0 ::: my_folder/*sh

Các -jđiều khiển có bao nhiêu quá trình t chạy song song và -j0có nghĩa là "tất cả chúng". -j20Thay vào đó, đặt nó thành một giá trị khác (ví dụ ) để chạy các tập lệnh theo đợt.


1
lưu ý: đó cũng là parallellệnh từ moreutilsgói. Cách sử dụng ví dụ: parallel -j 20 -- my_folder/*.sh(Không giống như GNU parallel, -j0sẽ chạy các tập lệnh một lần).
jfs

1
@jfs điểm tốt. Nhưng lưu ý rằng sudo apt install parallelsẽ thay thế tệp trong tệp /usr/bin/parallelsong song với GNU. Vì vậy, miễn là bạn cài đặt nó, như câu trả lời của tôi cho thấy, nó sẽ hoạt động như mong đợi.
terdon

Có, tôi đã phát hiện ra điều đó một cách khó khăn khi thử parallelcác lệnh không thành công từ hướng dẫn trong khi viết câu trả lời của tôi để đề xuất song song GNU.
jfs

9

Để chạy tất cả các tập lệnh cùng một lúc (song song) sử dụng:

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

Để chạy cái này sau cái khác (tuần tự), hãy sử dụng:

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

Tăng cường cho ý kiến

Nếu bạn có 200 tập lệnh bạn muốn chạy cùng một lúc (có thể làm hỏng máy BTW), hãy sử dụng tập lệnh này:

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

Đặt các thuộc tính tập lệnh thành thực thi với lệnh:

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

Lần đầu tiên bạn chạy tập lệnh, nó sẽ chỉ lặp lại tên của 200 tập lệnh mà nó sẽ thực thi. Khi bạn hài lòng, đúng tên đang được chọn, chỉnh sửa tập lệnh và thay đổi dòng này:

    echo bash "$Script" &

đến:

    bash "$Script" &

Có ba cách bạn có thể gọi một tập lệnh bash từ một cách khác như được trả lời ở đây:

  1. Làm cho tập lệnh khác có thể thực thi được, thêm #!/bin/bashdòng ở trên cùng và đường dẫn của tệp tới $PATHbiến môi trường. Sau đó, bạn có thể gọi nó như một lệnh bình thường;

  2. Hoặc gọi nó bằng lệnh nguồn (bí danh là.) Như thế này : source /path/to/script;

  3. Hoặc sử dụng lệnh bash để thực thi nó : /bin/bash /path/to/script;

Trong trường hợp của OP, một hoặc nhiều hơn 200 tập lệnh không chứa #!/bin/bashdòng đầu tiên của shebang trong tệp. Như vậy tùy chọn 3. đã được sử dụng.


200 tập lệnh đang chạy cùng một lúc

Một bình luận đã được đưa ra về việc họ có "chạy cùng một lúc" hay không. Trên hệ thống 8 CPU thông thường, 25 tập lệnh sẽ chia sẻ cùng lúc một CPU nhưng chỉ có một tập lệnh sẽ thực thi tại một thời điểm cho đến khi hết thời gian (tính bằng mili giây). Sau đó, công việc tiếp theo sẽ nhận được phần chia sẻ công bằng của nó là mili giây, rồi công việc tiếp theo, v.v., v.v.

Nói một cách dễ hiểu, chúng ta có thể nói 200 công việc đang chạy "đồng thời" nhưng không "đồng thời" trên 8 CPU tương đương với 25 công việc trên mỗi CPU:

chủ đề state.png

Hình ảnh trên và ý kiến ​​dưới đây từ bộ lập lịch kernel Linux

thời gian lát.png


cảm ơn bạn .. điều là trong trường hợp thực tế của tôi, tôi có hơn 200 tập lệnh để chạy. vậy có cách nào để tôi có thể chạy tất cả chúng chỉ bằng một lệnh (tức là không cần viết tên tệp của chúng) không?
aaaaa

@aaaaa Tôi đã thay đổi câu trả lời cho 200 tập lệnh.
WinEunuuchs2Unix

cảm ơn. nó hoạt động .. điều duy nhất tôi phải thêm vào dòng cuối cùng của bạn là 'bash'. nếu không thì tôi bị 'cho phép'.
aaaaa

1
@aaaaa Bạn có thực sự thích tất cả hơn 200 tập lệnh chạy cùng một lúc không, hoặc bạn muốn có một số lượng nhỏ hơn (giả sử 10) chạy cùng một lúc, với các tập lệnh khác được xếp hàng để chạy khi một hoặc nhiều tập lệnh kết thúc và số tập lệnh hiện đang chạy giảm xuống dưới số đó? (Nếu bạn quan tâm đến các giải pháp như vậy, tôi khuyên bạn nên chỉnh sửa câu hỏi của mình bằng thông tin về số lượng kịch bản bạn có, thời gian chúng chạy, thời gian thực hiện, v.v.)
Eliah Kagan

@aaaaa Cảm ơn bạn đã phản hồi. Tôi đã cập nhật câu trả lời để bao gồm bashtiền tố để gọi tập lệnh.
WinEunuuchs2Unix

3

Có một công cụ cho việc này, đọc man run-parts.

Ví dụ: tôi làm:

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

trong kịch bản sao lưu Palm Pilot của tôi. ${visorhome}/pbackup.d/:

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

1
@ eliah-kagan Chạy "hơn 200 tập lệnh" "cùng một lúc" dường như không khôn ngoan. Nó có thể là một cách tốt để kiểm tra căng thẳng một hệ thống
ví von

Điểm tốt. Tôi nghĩ rằng bạn vẫn có thể muốn đề cập đến việc run-partsthực thi các tập lệnh một cách tuần tự chứ không phải tất cả cùng một lúc như OP yêu cầu. Tuy nhiên, bạn đúng, việc chạy 200 tập lệnh cùng một lúc khó có thể thực hiện giống như chạy 5 - và ngay cả khi chạy tất cả chúng cùng một lúc không gây ra bất kỳ vấn đề nào, điều đó vẫn có thể không cần thiết. Tôi đã nhận xét để đề nghị OP làm rõ sở thích của họ về vấn đề này.
Eliah Kagan

run-partssẽ không chạy các tập lệnh (chúng có một dấu chấm trong tên:my_folder/*.sh
jfs

1
run-partsrất_ yêu cầu tên tệp cụ thể cho một số lý do lạ. Nó sẽ không khởi chạy tên tệp với phần mở rộng, vì vậy tôi sợ điều này sẽ không hoạt động ở đây.
terdon

1

Để chạy tất cả các *.shtập lệnh trong my_folderthư mục cùng một lúc bằng cách sử dụng xargs:

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

Để giới hạn số lượng tập lệnh được thực thi đồng thời thành 10:

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

Đó là một thực tế xấu để sử dụng đầu ra của lsmột tập lệnh. Sử dụng findsẽ an toàn hơn nhiều. Đây là mục đầu tiên ở đây: mywiki.wooledge.org/BashPit thác # for_f_in_.24.28ls_.2A.mp3.29
Joe

@Joe nói chung, đó là sự thật. Tôi không thấy vấn đề trong trường hợp cụ thể này.
jfs

Đó là bởi vì bạn đã biết về nó. Mọi người đến đây sau này có thể không.
Joe

@Joe đừng theo giáo điều một cách mù quáng. Hãy suy nghĩ cho bản thân bạn hơn một lựa chọn tốt hơn so với lựa chọn khác là sự đánh đổi trong trường hợp của bạn.
jfs

Đó không phải là một giáo điều. Tôi bị dị ứng với những người đó. Nhưng tôi đã thấy những thứ ls có thể phát ra. Phân tích cú pháp đầu ra của con người không đáng tin cậy. Không có động lực nào cho các nhà phát triển để giữ
Joe
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.