수천 개의 노드에 연결하고 실행된 명령에 대해 약 5개의 값을 반환하는 RHEL 서버의 bash에서 실행되는 스크립트가 있습니다. 이는 RHEL 서버에서만 정보를 수집합니다.
잘 작동하지만 문제는 다음 명령을 실행할 때 일부 노드가 정지된다는 것입니다.
rpm -q <package-name>
rpm --queryformat '%{installtime:date} %{name}\n' -q <package-name>
이제 이렇게 하면 내 스크립트가 확실히 중지되므로 ssh 명령에 대한 시간 제한을 설정하고 일부 원격 명령이 실행될 때까지 너무 오랫동안(예: 10초) 기다리면 ssh 세션을 종료하고 싶습니다. 이런 일이 발생하면 시간 초과되어 SSH 세션을 종료하고 다음 노드로 이동하고 싶습니다. 어떻게 해야 하나요?
이것은 현재 정보를 추출하여 dump라는 변수에 저장하는 스크립트의 일부입니다. [나의 불쌍한 스크립트는 무시하세요. 저는 여기에 처음입니다.]
dump=$(ssh -o ServerAliveCountMax=1 -o ServerAliveInterval=10 -o ConnectTimeout=10 -o BatchMode=yes $i "cat /proc/meminfo | grep -i \"memtotal\" | cut -d \":\" -f2 | tr -d \" \" | tr -d \"kB\"; cat /etc/redhat-release | cut -d \" \" -f7; dmidecode | grep -i \"prod\" | grep -vi \"desktop\" | grep -iv \"id\" | cut -d \" \" -f3,4| tr \" \" \"_\" ; uptime | cut -d \" \" -f4,5 | tr \" \" \"_\" | tr -d \",\"; service kdump status 2>/dev/null | tr \" \" \"_\";");
지속시간이 너무 길면 타임아웃을 할 수 있는 방법이 있나요?
내가 시도한 것:
(ssh -q -o Batchmode=yes -o PasswordAuthentication=no -o ConnectTimeout=1 $i "rpm --queryformat '%{installtime:date} %{name}\n' -q \"kexec-tools\" | cut -d \" \" -f1,2,3,4|tr \" \" \"_\"" > /dev/null) & pid=$!
(sleep 10 && kill -HUP $pid ) 2>/dev/null & watcher=$!
if wait $pid 2>/dev/null; then
pkill -HUP -P $watcher
wait $watcher
else
echo -e "$i Unable to ssh" >> res && continue
fi
그러나 이 방법으로는 원격 rpm 명령의 결과를 저장할 수 없습니다.
어떤 도움이라도 대단히 감사하겠습니다.
답변1
컬렉션을 병렬화하려면 GNU Parallel을 사용하세요.
parallel --slf rhel-nodes --tag --timeout 1000% --onall --retries 3 \
"rpm -q {}; rpm --queryformat '%{installtime:date} %{name}\n' -q {}" \
::: bash bc perl
노드를 에 넣으세요 ~/.parallel/rhel-nodes
.
--tag
노드 이름이 출력 앞에 추가됩니다. --timeout 1000%
명령 실행 시간이 중앙값보다 10배 더 오래 걸릴 경우 해당 명령이 종료됨을 나타냅니다. --onall
모든 명령은 모든 서버에서 실행됩니다. --retries 3
실패하면 명령이 최대 3번 실행됩니다. ::: bash bc perl
테스트하려는 패키지입니다. 패키지가 많은 cat packages | parallel ...
경우 parallel ... ::: packages
.
GNU Parallel은 동일한 컴퓨터 또는 SSH를 통해 액세스할 수 있는 여러 컴퓨터에서 작업을 병렬로 쉽게 실행할 수 있게 해주는 범용 병렬 처리기입니다.
4개의 CPU에서 32개의 서로 다른 작업을 실행하려는 경우 병렬화하는 간단한 방법은 각 CPU에서 8개의 작업을 실행하는 것입니다.
대신, GNU Parallel은 작업이 완료되면 새로운 프로세스를 생성하여 CPU를 활성 상태로 유지하여 시간을 절약합니다.
설치하다
배포판에 GNU Parallel이 패키지되어 있지 않으면 루트 액세스 없이 개인 설치를 수행할 수 있습니다. 이 작업은 10초 안에 완료할 수 있습니다.
(wget -O - pi.dk/3 || curl pi.dk/3/ || fetch -o - http://pi.dk/3) | bash
다른 설치 옵션은 다음을 참조하세요.http://git.savannah.gnu.org/cgit/parallel.git/tree/README
더 알아보기
더 많은 예시 보기:http://www.gnu.org/software/parallel/man.html
소개 비디오 보기:https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1
이 튜토리얼을 살펴보세요:http://www.gnu.org/software/parallel/parallel_tutorial.html
지원을 받으려면 이메일 목록에 가입하세요.https://lists.gnu.org/mailman/listinfo/parallel
답변2
이 문제를 해결해 주셔서 감사합니다.
나는 이제 이 문제를 해결했고 필요한 해결책은 너무 간단해서 지금은 바보 같은 느낌이 듭니다.
이전에 사용했던 코드에서는
(ssh -q -o Batchmode=yes -o PasswordAuthentication=no -o ConnectTimeout=1 $i "rpm --queryformat '%{installtime:date} %{name}\n' -q \"kexec-tools\" | cut -d \" \" -f1,2,3,4|tr \" \" \"_\"" > /dev/null) & pid=$!
내가 해야 할 일은 모든 출력을 로컬 컴퓨터의 파일로 리디렉션하는 것뿐입니다. 그게 다야.
(ssh -q -o Batchmode=yes -o PasswordAuthentication=no -o ConnectTimeout=1 $i "rpm --queryformat '%{installtime:date} %{name}\n' -q \"kexec-tools\" | cut -d \" \" -f1,2,3,4|tr \" \" \"_\"" > **test**) & pid=$!
제가 답변을 게시하기로 결정한 유일한 이유는 귀하가 제공한 답변에 외부 도구/코드를 가져와서 사용해야 하기 때문인데, 이는 제가 하고 싶지 않은 일입니다. 대신 소프트웨어 패키지나 OS 버전에 의존하지 않고 적용할 수 있는 솔루션을 원합니다.
그럼에도 불구하고 감사합니다!