원격 호스트에 SSH를 통해 접속하고 비밀번호를 변경하는 스크립트가 필요합니다.

원격 호스트에 SSH를 통해 접속하고 비밀번호를 변경하는 스크립트가 필요합니다.

그래서 최근에 저는 원격 Unix 호스트에 로그인하여 비밀번호를 변경하는 작은 스크립트를 개발해 왔습니다. 저는 Expect에 대해 많은 경험을 해본 적이 없기 때문에 상향 학습 곡선이었습니다.

지금까지 내 스크립트는 다음과 같습니다.

#!/usr/bin/expect

#Setting variables based on their location in the original script call
set username [lrange $argv 0 0]
set password [lrange $argv 1 1]
set server [lrange $argv 2 2]
set port [lrange $argv 3 3]
set changeuser [lrange $argv 4 4]
set newpassword [lrange $argv 5 5]
set yesval yes
set prompt "::>"


set timeout 60

spawn ssh -p $port $username@$server 
match_max 100000

expect "yes/no" {
    send "yes\r"
    expect "*?assword" { send "$password\r" }
} "*?assword" { send "$password\r" }
expect "::>" {
    send_user "ssh connection succeeded\n"
} "*?assword" { send_user "\nssh connection failed due to wrong    password\n"; exit 2}

send -- "\r"
expect "::>" {send "security login password -username $changeuser\r "}
expect "Enter a new password:*" {send "$newpassword\r"}
expect "Enter it again:*" {send "$newpassword\r"}
expect "::>" {send "exit\r";send_user "\npassword change successful for    $changeuser\n"}
expect "Enter a new password:*" { send "exit\r";send_user "\npassword change not successful for $changeuser\n"}

아이디어는 이것이 작은 프로세스를 자동화한다는 것입니다. 그러나 스크립트는 시스템에 성공적으로 로그인한 다음 아무것도 제공하지 않고 비밀번호 재설정을 진행하지 않으므로 기본적으로 ssh 이후에 중지됩니다.

업데이트: 비밀번호 재설정 명령을 실행하기 전에 "send --"\r""를 사용하여 빈 줄 문제를 해결하도록 관리되었습니다. 이제 스크립트가 완료될 때까지 실행되지만 두 번째 확인에서는 잘못된 비밀번호를 입력한 것으로 보입니다. 다음 출력을 추가했습니다.

::> ssh connection succeeded
::> security login password -username ######

Enter a new password:
Enter it again:

Error: Passwords didn't match.

::>
password change successful for ######
exit
Goodbye

업데이트 2:

먼저 지금까지 도움을 주신 모든 분들께 감사드립니다. 스크립트를 디버그 모드로 전환하고 다시 실행하여 변수 설정 방법을 변경했습니다.

이것은 디버그 모드의 출력이며 필요한 비밀번호가 모두 동일하므로 왜 실패하는지 잘 모르겠습니다.

expect: set expect_out(0,string) "Enter a new password: "
expect: set expect_out(spawn_id) "exp5"
expect: set expect_out(buffer) " security login password -username user\r\n\r\nEnter a new password: "
send: sending "Passtest123\r" to { exp5 }

expect: does "" (spawn_id exp5) match glob pattern "Enter it again:*"? no

Enter it again:
expect: does "\r\nEnter it again: " (spawn_id exp5) match glob pattern "Enter it again:*"? yes
expect: set expect_out(0,string) "Enter it again: "
expect: set expect_out(spawn_id) "exp5"
expect: set expect_out(buffer) "\r\nEnter it again: "
send: sending "Passtest123\r" to { exp5 }

expect: does "" (spawn_id exp5) match glob pattern "Error: Passwords didn't match.*"? no


expect: does "\r\n" (spawn_id exp5) match glob pattern "Error: Passwords didn't match.*"? no

오류: 비밀번호가 일치하지 않습니다.

답변1

답변은 아니지만 서식이 필요한 주석입니다. 스크립트 매개변수를 가져오는 방식이 미묘하게 잘못되었습니다. lrange반환목록, 목록을 문자열화하면 일부 특수 문자가 이스케이프됩니다. 이는 보내는 비밀번호에 영향을 미칩니다. 대신 이렇게 하세요:

set username [lindex $argv 0]
set password [lindex $argv 1]
set server [lindex $argv 2]
set port [lindex $argv 3]
set changeuser [lindex $argv 4]
set newpassword [lindex $argv 5]

또는

lassign $argv username password server port changeuser newpassword

동일한 비밀번호를 두 번 보내셨기 때문에 해당 오류가 발생하는 이유를 이해할 수 없습니다. 디버깅을 추가하면 문제가 드러날 수 있습니다.

관련 정보