シェルスクリプトでssh越しにコマンドを実行する

タイトルからして頭悪い感じですが、必要に迫られてちょっと調べてみました。
sshにパスワードをパイプする方法。

スポンサーリンク

telnetなら簡単じゃね?

たとえば telnet であれば echo と sleep を使って自動ログインしてコマンド実行などが簡単にできます。

#!/bin/bash
sleep 1; echo "username"
sleep 1; echo "password"
sleep 5; echo "ls -l"
sleep 1; echo "exit"

こんな感じで使います。

$./cmd.sh | telnet example.com

うわぁ・・・頭悪い感じですね。。。

sshだとできなくね?

ところがsshだとパスワードをパイプできません。

$ echo password | ssh user@example.com
Pseudo-terminal will not be allocated because stdin is not a terminal.
user@example.com's password:

この手のスクリプトを組む場合は、パスフレーズなしの鍵認証にして、
$ssh user@example.com ls -l
とかするか、expect というのを使うのが定石っぽいです。

パスフレーズなしの鍵認証にしておくのが精神衛生上一番良い気がします。

とはいえ、大人の事情でexpectを入れるとか、パスフレーズなしで認証できるようにするとかができないことはよくありますよね。

プログラムのインストールはダメなのに平文でユーザ名とパスワードをサーバ上に置いておくのはOKってどゆことよ。。。

閑話休題

ssh askpass でできそうじゃね?

色々調べたところ、$SSH_ASKPASSを使えばできそうだということがわかったので早速検証してみました。
GUIプログラムでユーザにsshのパスワードを入力させるために用意された仕組みですが、stdinからSSHのパスワードを読ませることができます。というか、できました。

#!/bin/bash
if [ -n "$PASSWORD" ]; then
  cat <<< "$PASSWORD"
  exit 0
fi
read PASSWORD
export SSH_ASKPASS=$0
export PASSWORD
export DISPLAY=dummy:0
exec setsid "$@"

エラー処理?
(´・ω・`)知らんがな。

適当に存在しないDISPLAYを指定して、setsidでttyからdetachしてます。

で、このスクリプトをssh_pass.shとかにしておいて、こんな感じで使います。
$echo password | ./ssh_pass.sh ssh user@example.com "ls -a"

スポンサーリンク

フォローする