私はこれらをスクリプトで実行しようとしています。リモートホストでいくつかのコマンドを実行する必要があります。現在、私はこれをやっています:
ssh root@Host 'bash -s' < command1
ssh root@Host 'bash -s' < command2
ssh root@Host 'bash -s' < command3
ただし、これはサーバーに繰り返し接続する必要があることを意味します。これにより、コマンドの処理の間隔が大幅に長くなります。私はこのようなものを探しています:
varSession=$(ssh root@Host 'bash -s')
varSeesion < command1
varSeesion < command2
varSeesion < command3
繰り返しますが、これらのコマンドをスクリプトで実行する必要があります。 screen
を確認しましたが、スクリプトで使用できるかどうかはわかりません。
ControlMaster
および ControlPersist
を使用して、コマンドが終了した後も接続を維持できます。
ControlMaster
と組み合わせて使用すると、最初のクライアント接続が閉じられた後、マスター接続がバックグラウンドで開いたままになることを指定します(将来のクライアント接続を待つ)。no
に設定すると、マスター接続はバックグラウンドに配置されず、最初のクライアント接続が閉じられるとすぐに閉じます。yes
または_0
_に設定すると、マスター接続はバックグラウンドで無期限に(「_ssh -O exit
_」などのメカニズムによって強制終了またはクローズされるまで)残ります。秒単位の時間、またはsshd_config(5)
に記載されているいずれかの形式の時間に設定されている場合、バックグラウンドマスター接続は、指定された時間(クライアント接続なしで)アイドル状態が続いた後、自動的に終了します。
したがって、最初のSSHコマンドは接続用の制御ファイルをセットアップし、他の2つはその制御ファイルを介してその接続を再利用します。 _~/.ssh/config
_は次のようになります。
_Host host
User root
ControlMaster auto
ControlPath /tmp/ssh-control-%C
ControlPersist 30 # or some safe timeout
_
また、スクリプトには他の変更は必要ありません。
StackOverflowの 類似の質問 からヒントを取得し、bashを使用することができますここにドキュメント:
ssh root@Host 'bash -s' << EOF
command1
command2
command3
EOF
expect
スクリプトを使用できます。 ssh接続を自動化し、リモートマシンでコマンドを実行できます。 このコード は、ssh接続の自動化に少し光を当てるべきです。
あなたはこのようなものを探しています。次のコードをファイルに保存しますfoo.expect
#login to the remote machine
spawn ssh username@hostname
expect "?assword" { send "yourpassword\r"}
#execute the required commands; following demonstration uses echo command
expect "$ " {send "echo The falcon has landed\r"}
expect "$ " {send "echo The falcons have landed\r"}
expect "$ " {send "echo Will the BFR? land? \r"}
#exit from the remote machine
expect "$ " {send "exit\r"}
expect foo.expect
として実行します
アプリケーションがこのスクリプトを実行することを期待する必要があります。コマンドapt-get install expect
でインストールできます
この本 は、予想されるスクリプトの探索に役立ちます。ハッピースクリプト!
ControlPath
とControlPersist
正しい方法、提案 muruの回答 、私は代替案を提示したいと思います:
Sshの出力に使用するFIFOを作成します
このファイルは、自信のあるパスに作成する必要があります
mkfifo $HOME/sshfifo
long-runningコマンドを実行:
exec 8> >(exec ssh user@Host /bin/bash >$HOME/sshfifo
exec 9<$HOME/sshfifo
その後、あなたはもうFIFOを必要としません
rm $HOME/sshfifo
これで、接続からコマンドを送信および受信する準備ができました。
echo >&8 uptime
while read -t .002 -r -u 9 answer;do echo "$answer";done
注意:0.002 seconds
は、不十分なインターネット接続では不十分な場合があります...リクエストのタイプによっては、タイムアウトが役に立たない場合があります。これは、どのような種類の対話に注意を向けるかに適応することができます。
等々...
myremote() {
echo "$@" >&8
while IFS= read -t .02 -r -u 9 answer;do
echo "$answer"
done
}
これは、明示的にこの接続を閉じるまで残ります。
exec 8>&-
exec 9<&-
これは完璧ではありません。あなたは出来る
バインド[〜#〜] stderr [〜#〜]も2番目のfifoで
mkfifo $HOME/sshfifo{out,err}
exec 8> >(exec ssh user@Host /bin/bash >$HOME/sshfifoout 2>$HOME/sshfifoerr)
exec 9<$HOME/sshfifoout
exec 10<$HOME/sshfifoerr
rm $HOME/sshfifo{out,err}
インタラクティブbashを使用し、タイムアウトを減らす
mkfifo $HOME/sshfifo{out,err}
exec 8> >(exec ssh -tT user@Host /bin/bash -i >$HOME/sshfifoout 2>$HOME/sshfifoerr)
exec 9<$HOME/sshfifoout
exec 10<$HOME/sshfifoerr
rm $HOME/sshfifo{out,err}
echo >&8 'set -i;PS1="ReAdY aS BoUnD\\n"'
while IFS= read -d '' -rn 1 -t .02 -u 9 foo;do echo -n "$foo";done
while IFS= read -d '' -rn 1 -t .02 -u 10 foo;do echo -n "$foo";done
...次に/^ReAdY aS BoUnD$/
からのfd/10
を最後のコマンドの実行の終了のマーカーとして監視しているため、タイムアウトを回避できますSTDERR(-u 10
)、次にSTDOUT(-u 9 -t .002
)のtimemoutを減らします。
複数の接続をopenして一緒に使用することも可能です
mkfifo $HOME/sshfifo
exec 8> >(exec ssh user1@hostA /bin/bash >$HOME/sshfifo 2>&1)
exec 9<$HOME/sshfifo
rm $HOME/sshfifo
mkfifo $HOME/sshfifo
exec 11> >(exec ssh user2@hostB /bin/bash >$HOME/sshfifo 2>&1)
exec 12<$HOME/sshfifo
rm $HOME/sshfifo
その後
tee <<<uptime /dev/fd/8 >&11
read -u 9 -t .02 ansA
read -u 12 -t .02 ansB
同じコマンドを同時に両端に送信するには...
cat
を使用してすべてのファイルを連結し、それらをssh
にパイプすることができます。
cat command1 command2 command3 | ssh root@Host 'bash -s'