Chạy nhiều hàm bash trong nền và đợi cho đến khi chúng quay trở lại


14

Đây là một tập lệnh đơn giản chạy nvidia-smilệnh trên nhiều máy chủ và lưu kết quả đầu ra của nó vào một tệp chung. Mục tiêu ở đây là làm cho nó chạy không đồng bộ .

&ở cuối của process_host()chức năng gọi đủ? Kịch bản của tôi có đúng không?

#!/bin/bash

HOSTS=(host1 host2 host3)
OUTPUT_FILE=nvidia_smi.txt

rm $OUTPUT_FILE

process_host() {
    host=$1
    echo "Processing" $host
    output=`ssh ${host} nvidia-smi`
    echo ${host} >> $OUTPUT_FILE
    echo "$output" >> $OUTPUT_FILE
}

for host in ${HOSTS[@]}; do
    process_host ${host} &
done;

wait
cat $OUTPUT_FILE

Câu trả lời:


13

Có, nhưng đầu ra của bạn có thể bị cắt xén. Tốt hơn là có chức năng ghi đầu ra của nó vào một tệp cụ thể tùy thuộc vào tên máy chủ và sau đó để tập lệnh chính nối kết quả (và dọn sạch).

Ngoài ra, bạn nên trích dẫn gấp đôi các biến của bạn. Sao chép và dán tập lệnh vào ShellCheck .

Có lẽ một cái gì đó như thế này:

#!/bin/bash

hosts=( host1 host2 host3 )
outfile="nvidia_smi.txt"

rm -f "$outfile"

function process_host {
    local host="$1"
    local hostout="$host.out"
    printf "Processing host '%s'\n" "$host"
    echo "$host" >"$hostout"
    ssh "$host" nvidia-smi >>"$hostout"
}

for host in "${hosts[@]}"; do
    process_host "$host" &
done

wait

for host in "${hosts[@]}"; do
    hostout="$host.out"
    cat "$hostout"
    rm -f "$hostout"
done >"$outfile"

cat "$outfile"

Vòng lặp cuối cùng có thể được thay thế bởi

cat "${hosts[@]/%/.out}" >"$outfile"
rm -f "${hosts[@]/%/.out}"

Tôi nhận được chính xác đầu ra tôi muốn nhận, điều gì có thể sai ở đây?
cú pháp

2
@ Nếu, ví dụ, máy chủ đầu tiên phản hồi chậm, Processing host1sẽ được theo sau Processing host2và đầu ra từ host2chứ không phải đầu ra từ host1.
Kusalananda
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.