SSH를 통해 비밀번호로 보호된 여러 컴퓨터에 로그인하고 다시 시작하는 방법은 무엇입니까?

SSH를 통해 비밀번호로 보호된 여러 컴퓨터에 로그인하고 다시 시작하는 방법은 무엇입니까?

SSH를 통해 비밀번호로 보호된 여러 컴퓨터를 재부팅하는 bash 스크립트를 작성하려고 합니다. .txt 파일에 모든 IP 목록이 있고 스크립트가 거기에서 IP를 읽도록 하려고 합니다. 내 Mac에는 sshpass가 없기 때문에 Expect 명령을 사용하여 장난을 쳤습니다. sshpass 없이 할 수 있는 방법이 있나요?

지금까지 나는 이것을 가지고 있습니다 :

#!/bin/bash

for server in 'testreboot.txt'; do
expect -c 'spawn ssh -o StrictHostKeyChecking=no -o ConnectTimeout=5 
administrator@$server "sudo shutdown -r now"; expect "Password:"; send 
"password\r"; interact'
done

testreboot.txt에는 테스트 머신의 IP 주소만 나열합니다. 가능합니까, 아니면 변수에 할당해야 합니까? 실행하려고 하면 계속해서 다양한 오류가 발생합니다.

답변1

문자열을 작은따옴표로 묶어서 셸이 삽입하는 것을 방지합니다 $server. TCL( 코드 작성 방식)도 이 형식을 사용하여 변수를 삽입하지만 expectTCL 코드에서는 $server이 형식을 사용하지 않습니다 . set server ...따라서 쉘이 이를 삽입하지 않고 TCL이 이를 설정하지 않기 때문에 오류가 발생합니다. 한 가지 방법은 TCL 표현식을 큰따옴표로 묶어서 쉘이 $server쉘 변수에 삽입할 수 있도록 하는 것입니다.

$ server=example; expect -c 'puts $server'
can't read "server": no such variable
    while executing
"puts $server"
$ server=example; expect -c "puts $server"
example
$ 

그러나 이는 "쉘 보간을 방해하지 않도록 TCL 코드의 모든 항목을 이스케이프해야 함을 의미합니다. 이는 특히 명령이 더 길고 복잡해짐에 따라 빠르게 추악해지고 디버그하기 어려워질 수 있습니다.

$ server=example; expect -c "puts \"a server named '$server'\""
a server named 'example'
$ 

또 다른 옵션은 매개변수를 TCL 변수로 읽는 것입니다. 그러나 아쉽게도 -c플래그 코드는expect 매개변수 목록에 접근할 수 없습니다.매개변수 목록이 TCL에 사용 가능해지기 전에 char *argv[]코드가 실행되기 때문입니다 . -c따라서 이를 TCL 변수로 사용하려면 $server스크립트를 TCL로 다시 작성해야 합니다.

#!/usr/bin/env expect

set fh [open testreboot.txt r]

while {[gets $fh server] >= 0} {
    spawn -noecho ssh -o StrictHostKeyChecking=no -o ConnectTimeout=5 \
       administrator@$server
    expect -ex "Password:"
    send "Hunter2\r"
    expect -ex {$ }
    send "sudo shutdown -r now\r"
    expect -ex "Password:"
    send "Hunter2\r"
    interact
}

이를 위해서는 향상된 오류 처리, 시간 초과, 더 나은 쉘 프롬프트 일치 등이 필요할 수 있습니다.

관련 정보