Đa luồng / Ngã ba trong tập lệnh bash


9

Tôi đã viết một tập lệnh bash có định dạng sau:

#!/bin/bash
start=$(date +%s)
inFile="input.txt"
outFile="output.csv"

rm -f $inFile $outFile

while read line
do

    -- Block of Commands

done < "$inFile"

end=$(date +%s)

runtime=$((end-start))

echo "Program has finished execution in $runtime seconds."

Các whilevòng lặp sẽ đọc từ $inFile, thực hiện một số hoạt động trên dòng và đổ kết quả trong $outFile.

$inFiledài hơn 3500 dòng, kịch bản sẽ mất 6-7 giờ để thực thi hoàn toàn. Để giảm thiểu thời gian này, tôi dự định sử dụng đa luồng hoặc chuyển đổi trong tập lệnh này. Nếu tôi tạo 8 tiến trình con, 8 dòng từ $inFileđó sẽ được xử lý đồng thời.

Điều này có thể giải quyết như thế nào?


Hãy cẩn thận: các tập lệnh khác nhau sẽ cần phải ghi vào các tệp khác nhau . Ngoài ra tập lệnh của bạn dưới dạng văn bản sẽ xóa tệp đầu vào là hành động đầu tiên!
pjc50

Câu trả lời:


10

GNUparallel được tạo ra cho loại điều này. Bạn có thể chạy tập lệnh của mình nhiều lần cùng một lúc, với các dữ liệu khác nhau từ đầu vào của bạn được truyền vào cho từng tập lệnh:

cat input.txt | parallel --pipe your-script.sh

Theo mặc định, nó sẽ sinh ra các quy trình theo số lượng bộ xử lý trên hệ thống của bạn, nhưng bạn có thể tùy chỉnh nó với -j N.

Một mẹo đặc biệt gọn gàng là tính năng gói shebang. Nếu bạn thay đổi dòng đầu tiên của tập lệnh Bash thành:

#!/usr/bin/parallel --shebang-wrap --pipe /bin/bash

và cung cấp dữ liệu cho dữ liệu đầu vào tiêu chuẩn thì tất cả sẽ diễn ra tự động. Điều này ít hữu ích hơn khi bạn có mã dọn dẹp phải chạy ở cuối, điều mà bạn có thể làm.

Có một vài điều cần lưu ý. Một là nó sẽ cắt dữ liệu đầu vào của bạn thành các phần liên tiếp và sử dụng từng phần một - nó không xen kẽ các dòng. Khác là nó được chia theo kích thước, mà không quan tâm đến có bao nhiêu hồ sơ. Bạn có thể sử dụng --block Nđể đặt kích thước khối khác nhau theo byte. Trong trường hợp của bạn, không quá một phần tám kích thước tệp sẽ đúng. Tệp của bạn có vẻ như đủ nhỏ để kết thúc tất cả trong một khối nếu không, điều này sẽ đánh bại mục đích.

Có rất nhiều tùy chọn cho các trường hợp sử dụng cụ thể khác nhau, nhưng hướng dẫn bao gồm mọi thứ khá tốt. Các tùy chọn bạn cũng có thể quan tâm bao gồm --round-robin--group.


1
Bạn đã kiểm tra dòng shebang đó? Shebang với nhiều đối số là không thể truy cập. Trên Linux, #!a b csẽ dẫn đến ["b c"], trong khi trên một số hệ thống khác, nó sẽ dẫn đến ["b", "c"].
nyuszika7h

1
Nó lặp lại các đối số của chính nó khi được sử dụng theo cách này (nếu không thì tùy chọn sẽ không được sử dụng nhiều).
Michael Homer

@MichaelHomer Tôi cần sử dụng GNU parallelđể quét các trang HTML. Bạn có thể xin vui lòng đi qua chủ đề này unix.stackexchange.com/questions/277609/...
Swatesh Pakhare
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.