이 스크립트가 있습니다.
#!/bin/sh
SERVERLIST=hosts
ICMD='cat /etc/redhat-release'
while read SERVERNAME
do
ssh $SERVERNAME $ICMD
done < "$SERVERLIST"
좋다 hosts
:
hostname
hostname
hostname
스크립트를 실행하면 ./run.sh
단일 호스트로만 이동하여 중지됩니다. 전체 호스트 목록을 읽지 못하는 이유는 무엇입니까?
답변1
ssh는 시작 속도를 높일 수 있는 stdin을 미리 읽으려면 원격 작업에 일부 데이터가 필요하다고 가정합니다. 따라서 첫 번째 작업이 호스트 목록의 나머지 부분을 차지합니다.
ssh -n
이 옵션을 사용하거나 리디렉션(예 : ssh < /dev/null
. 까다로운 사람으로서 나는 다음 두 가지를 모두 수행합니다 ssh -n < /dev/null <other ssh options>
.
원격 작업이 로컬 시스템에서 무언가를 읽도록 하려면 각 반복마다 이를 파이프하거나 여기에 문서화해야 합니다. 사용되는 경우에도 for <host>
ssh는 각 호스트에 대해 stdin에서 불확실한 양의 데이터 읽기를 시작합니다.
SSH를 통해 액세스하기 전에 항상 원격 호스트에 ping을 실행하여 상태를 확인합니다. IIRC에는 ping -W
하드 타임아웃 옵션이 있으며 ssh
알 수 없거나 죽은 호스트의 경우 DNS에 정지하거나 90초 이상 연결할 수 있습니다.
답변2
또한 이를 사용하면 pdsh
여러 호스트에서 명령을 병렬로 실행할 수 있습니다.
pdsh -w ^hostlist.txt -R ssh "cat /etc/redhat-release"
^
호스트 이름 목록이 포함된 파일을 정의합니다. 쉼표로 구분된 목록을 사용할 수도 있습니다.
pdsh -w host1,host2,host3,... -R ssh "cat /etc/redhat-release"
결과는 다음과 같습니다.
pdsh, -w raspi,raspi.local,192.168.0.3,localhost,127.0.0.1 -R ssh "cat /etc/issue"
raspi: Raspbian GNU/Linux 10 \n \l
raspi:
raspi.local: Raspbian GNU/Linux 10 \n \l
raspi.local:
192.168.0.3: Raspbian GNU/Linux 10 \n \l
192.168.0.3:
localhost: Debian GNU/Linux 10 \n \l
localhost:
127.0.0.1: Debian GNU/Linux 10 \n \l
127.0.0.1: