リモートホストに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""を使用して空白行の問題を解決するように管理されました。これでスクリプトが完了するまで実行されますが、2番目の確認では無効なパスワードを入力したようです。次の出力を追加しました。

::> 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

同じパスワードを2回送信したため、そのエラーが発生した理由を理解できません。デバッグを追加すると、問題が明らかになる可能性があります。

おすすめ記事