質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
bash

bash(Bourne-again-Shell)は sh(Bourne Shell)のインプリメンテーションに様々な機能が追加されたシェルです。LinuxやMac OS XではBashはデフォルトで導入されています。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

Q&A

解決済

1回答

13117閲覧

Expectのパスワード受け渡しができない

minhouse10

総合スコア41

bash

bash(Bourne-again-Shell)は sh(Bourne Shell)のインプリメンテーションに様々な機能が追加されたシェルです。LinuxやMac OS XではBashはデフォルトで導入されています。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

0グッド

1クリップ

投稿2018/03/15 11:18

編集2021/11/24 11:16

あるLinuxサーバーから、Expectコマンドを利用して複数台ある他のLinuxサーバーのIPアドレスをwhileで読み込ませて、順番にSCPコマンド自動化スクリプトを作成しておりますが、パスワード入力のプロンプトでどうしても処理がストップしてしまいます。どうもsendコマンドによるパスワード受け渡しがうまくできていないようです。

現象:以下パスワード入力プロンプトで止まってしまう

spawn scp test.txt ohm@192.168.38.194:/tmp
ohm@192.168.38.194's password:

フルコードは以下になります。どなたかご教授、アドバイス頂けますでしょうか?

#!/bin/bash ip_file='systems.txt' USER='ohm' PASS='#xxxxxxxx' TARGET_DIR='test.txt' CR_DIR='/tmp/' while read line || [ -n "${line}" ]; do expect -c " set timeout -1 spawn scp ${TARGET_DIR} ${USER}@${line}:${CR_DIR} expect { \" Are you sure you want to continue connecting (yes/no)? \" { send \"yes\r\" expect \"${USER}@${line}'s password: \" send \"${PASS}\r\" } exp_continue } interact " done < ${ip_file

修正箇所

コードを以下の様に変更した結果、パスワードプロンプトで停止せずスクリプトの実行は終了たが、scpの処理が実行されない。 expect { \" Are you sure you want to continue connecting (yes/no)? \" { send \"yes\r\" expect \"${USER}@${line}'s password:\" -re \"${USER}@${line}'s password:\" send \"${PASS}\r\" } -re \"${USER}@${line}'s password:\" { send \"${PASS}\r\" } interact "

scp -vオプションを付けて実行した結果になります。scpコマンドは実行されている事が確認。
[root@host]# bash scp_auto.sh
spawn scp -v test.txt ohm@22.222.22.222:/tmp
Executing: program /usr/bin/ssh host 22.222.22.222, user far, command scp -v -t /tmp
OpenSSH_6.6.1, OpenSSL 1.0.1e-fips 11 Feb 2013
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: /etc/ssh/ssh_config line 56: Applying options for *
debug1: Connecting to 22.222.22.222 [22.222.22.222] port 22.
debug1: Connection established.
debug1: permanently_set_uid: 0/0
debug1: identity file /root/.ssh/id_rsa type -1
debug1: identity file /root/.ssh/id_rsa-cert type -1
debug1: identity file /root/.ssh/id_dsa type -1
debug1: identity file /root/.ssh/id_dsa-cert type -1
debug1: identity file /root/.ssh/id_ecdsa type -1
debug1: identity file /root/.ssh/id_ecdsa-cert type -1
debug1: identity file /root/.ssh/id_ed25519 type -1
debug1: identity file /root/.ssh/id_ed25519-cert type -1
debug1: Enabling compatibility mode for protocol 2.0
debug1: Local version string SSH-2.0-OpenSSH_6.6.1
debug1: Remote protocol version 2.0, remote software version OpenSSH_7.2
debug1: match: OpenSSH_7.2 pat OpenSSH* compat 0x04000000
debug1: SSH2_MSG_KEXINIT sent
debug1: SSH2_MSG_KEXINIT received
debug1: kex: server->client aes128-ctr hmac-sha1 none
debug1: kex: client->server aes128-ctr hmac-sha1 none
debug1: kex: curve25519-sha256@libssh.org need=20 dh_need=20
debug1: kex: curve25519-sha256@libssh.org need=20 dh_need=20
debug1: sending SSH2_MSG_KEX_ECDH_INIT
debug1: expecting SSH2_MSG_KEX_ECDH_REPLY
debug1: Server host key: RSA c2:ae:1e:70:c4:82:7e:21:49:36:5d:4a:29:6a:2d:a9
debug1: Host '22.222.22.222' is known and matches the RSA host key.
debug1: Found key in /root/.ssh/known_hosts:18
debug1: ssh_rsa_verify: signature correct
debug1: SSH2_MSG_NEWKEYS sent
debug1: expecting SSH2_MSG_NEWKEYS
debug1: SSH2_MSG_NEWKEYS received
debug1: Roaming not allowed by server
debug1: SSH2_MSG_SERVICE_REQUEST sent
debug1: SSH2_MSG_SERVICE_ACCEPT received

debug1: Authentications that can continue: publickey,password,keyboard-interactive
debug1: Next authentication method: publickey
debug1: Trying private key: /root/.ssh/id_rsa
debug1: Trying private key: /root/.ssh/id_dsa
debug1: Trying private key: /root/.ssh/id_ecdsa
debug1: Trying private key: /root/.ssh/id_ed25519
debug1: Next authentication method: keyboard-interactive
debug1: Authentications that can continue: publickey,password,keyboard-interactive
debug1: Next authentication method: password

ohm@22.222.22.222's password: [root@host]#


修正後:
while read line || [ -n "${line}" ];
do
expect -c "
set timeout 5
spawn scp -v ${TARGET_DIR} ${USER}@${line}:${CR_DIR}
expect {
"${USER}@${line}'s password:"
send "${PASS}\n"
}
-re "[Pp]assword:" {
send "${PASS}\n"
}
interact
"
done < ${ip_file}

結果:
debug1: Next authentication method: password
ohm@22.222.22.222's password: usage: send [args] string
while executing
"send"
invoked from within
"expect {
"ohm@22.222.22.222's password:"
send "#!8102L#>t\n"
}"
[root@host]


修正版:成功!!

expect -c "
set timeout 5
spawn scp -v ${TARGET_DIR} ${USER}@${line}:${CR_DIR}
expect "${USER}@${line}'s password:" {
send "${PASS}\n"
}
expect "${USER}@${line}'s password:" {
send "${PASS}\n"
}
"

結果:
Sending file modes: C0755 0 test.txt
Sink: C0755 0 test.txt
test.txt 100% 0 0.0KB/s 00:00
debug1: client_input_channel_req: channel 0 rtype exit-status reply 0
debug1: channel 0: free: client-session, nchannels 1
debug1: fd 0 clearing O_NONBLOCK
debug1: fd 1 clearing O_NONBLOCK
Transferred: sent 2688, received 4328 bytes, in 0.1 seconds
Bytes per second: sent 25747.9, received 41457.1
debug1: Exit status 0

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

パスワード入力プロンプトで止まるということは、expectで引っかかってないってことでしょう。
正規表現でもっと幅広くexpectしてみてはどうでしょうか。例えば

expect { -re \"password:\" send \""${PASS}\r\" }

といった感じで。
上記のコードではコロンのあとにスペースがあるのもちょっと気になります。

(追記) expect部分、こうするとどうなるでしょう。

expect -c " set timeout -1 spawn scp ${TARGET_DIR} ${USER}@${line}:${CR_DIR} expect { \"Are you sure you want to continue connecting (yes/no)? \" { send \"yes\r\" expect \"${USER}@${line}'s password: \" send \"${PASS}\r\" } -re \"[Pp]assword:\" { send \"${PASS}\r\" } } expect eof "

-vの出力でパスワードをsendしていないので、expectあたりがちょっと変なのかも。
一段目の"Are you sure云々"のところは二回目からは出ないはずなので、外しちゃってもいいかも。

投稿2018/03/16 02:53

編集2018/03/16 05:29
rogueref

総合スコア727

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

minhouse10

2018/03/16 03:18

rogueref様、ご教授頂きありがとうございます! 色々基本的な知識が不足しており、お恥ずかしいかぎりです。アドバイスに従って上記のように変更した結果、パスワードプロンプトで停止せずにスクリプトは終了するようになりましたが、SCPコマンド自体が実行されず終了してしまっているようです。なにかお気づきの点ありましたら、よろしくお願いいたします。
rogueref

2018/03/16 04:37

パスワードプロンプトまで表示されて、スクリプトが終了しているのだったらscpは実行されているのでしょう。 scpでコピーしているときに表示されるプログレスメータ的な表示はパスワードプロンプトの次に表示されますか? 認証がエラーになっているとか、目的ディレクトリが違っていたということはありませんか? scp に -v オプションをつけてみるとどのようなメッセージがでるでしょうか。
minhouse10

2018/03/16 05:04

rogueref様、度々ありがとうございます!scp -vオプションを付けて実行した結果を上記に追加させて頂きました。ご指摘通り、scpコマンドは実行されている事が確認できていますね。
minhouse10

2018/03/16 05:10

すいません、ログの最後のプロンプトが返ってくる行を含めておりませんでしたので、追記させて頂きました。
minhouse10

2018/03/16 06:36

rogueref様、この度はいろいろとご教授頂き誠にありがとうございました!おかげ様でスクリプトがうまく動きファイルを転送する事に成功しました。修正箇所を追記させて頂きました。よろしければご確認いただければと存じます。ただexpectとsendの部分なぜ同じ構文を2度繰り返す必要があるのか謎です。。
rogueref

2018/03/16 06:43

なんにせよ解決してよかったです。 expectのところ一個だと動かないんですか? おかしいですねぇ。。
minhouse10

2018/03/16 06:51

改めてありがとうございます!300台ぐらいのLinuxサーバーにSCPしなくてはならなくなったので、このスクリプトで仕事がだいぶ効率化されます^^はい、一個目を無効にするとパスワードプロンプトで停止いたします。。。
rogueref

2018/03/16 06:53

うーん、おかしいけど動くんならそれでいいか(www 300台ですか。 それだとエラー検出のロジックも入れたほうがいいかもですね。
minhouse10

2018/03/16 07:31

ありがとうございます、はい、確かにSCPに失敗するケースも出てきそうなのでエラーロジックの適用も検討開始します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問