nvidia-smi
이는 여러 호스트에서 명령을 실행하고 해당 출력을 공통 파일에 저장하는 간단한 스크립트입니다 . 여기서 목표는 실행하는 것입니다.비동기적으로.
&
함수 호출이 끝나면 충분합니까 process_host()
? 내 스크립트가 맞나요?
#!/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
답변1
예, 스크립트는 정확하지만 출력이 깨졌거나 순서가 잘못되었을 수 있습니다. 함수가 호스트 이름을 기반으로 특정 파일에 출력을 쓴 다음 기본 스크립트가 결과를 연결하고 정리하도록 하는 것이 더 좋습니다.
또한 변수를 큰따옴표로 묶어야 합니다. 스크립트를 복사하여 붙여넣으세요.주택 검사.
어쩌면 다음과 같은 것일 수도 있습니다.
#!/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"
마지막 루프는 다음으로 대체될 수 있습니다.
cat "${hosts[@]/%/.out}" >"$outfile"
rm -f "${hosts[@]/%/.out}"
2016년 2021년의 이전 답변을 보면 오늘은 다음과 같은 코드를 작성할 수 있습니다.
#!/bin/sh
set -- host1 host2 host3
outfile=nvidia_smi.txt
for host do
ssh "$host" nvidia-smi >"$outfile-$host" &
done
echo 'Commands submitted, now waiting...'
wait
for host do
cat "$outfile-$host"
rm -f "$outfile-$host"
done >"$outfile"
echo 'Done.'
실제로 명명된 배열이 필요하지 않기 때문에 이는 더 짧습니다. 따라서 대신 /bin/sh
으로 실행할 수 있습니다 bash
. 대신 연결할 호스트 목록이 위치 매개변수 목록에 보관됩니다. 또한 루프 내부의 정보 출력과 쉘 함수(실제로 많은 작업을 수행하지는 않음)를 제거했습니다.
사용되었을 수 있는 파일 이름을 구성하는 대신 적절한 임시 파일을 사용하는 변형:
#!/bin/sh
set -- host1 host2 host3
outfile=nvidia_smi.txt
for host do
tmpfile=$(mktemp)
ssh "$host" nvidia-smi >"$tmpfile" &
set -- "$@" "$tmpfile"
shift
done
echo 'Commands submitted, now waiting...'
wait
# Concatenate the output files and delete them.
cat -- "$@" >"$outfile"
rm -f -- "$@"
echo 'Done.'
이는 위치 매개변수의 호스트 이름을 해당 호스트에 대한 출력이 포함된 임시 파일의 경로 이름으로 대체합니다.