web-dev-qa-db-ja.com

リモートSSHセッションを「保存」しますか?

私はこれらをスクリプトで実行しようとしています。リモートホストでいくつかのコマンドを実行する必要があります。現在、私はこれをやっています:

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を確認しましたが、スクリプトで使用できるかどうかはわかりません。

12
SayantanRC

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
_

また、スクリプトには他の変更は必要ありません。

29
muru

StackOverflowの 類似の質問 からヒントを取得し、bashを使用することができますここにドキュメント

ssh root@Host 'bash -s' << EOF
  command1
  command2
  command3
EOF
7
Twinkles

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でインストールできます

この本 は、予想されるスクリプトの探索に役立ちます。ハッピースクリプト!

4
daedalus_hamlet

1つ以上のファイル記述子の独立[〜#〜] ssh [〜#〜]接続

ControlPathControlPersist正しい方法、提案 muruの回答 、私は代替案を提示したいと思います:

方法

  1. Sshの出力に使用するFIFOを作成します

    このファイルは、自信のあるパスに作成する必要があります

    mkfifo $HOME/sshfifo
    
  2. long-runningコマンドを実行:

    exec 8> >(exec ssh user@Host /bin/bash >$HOME/sshfifo
    exec 9<$HOME/sshfifo
    
  3. その後、あなたはもうFIFOを必要としません

    rm $HOME/sshfifo
    
  4. これで、接続からコマンドを送信および受信する準備ができました。

    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
    }
    
  5. これは、明示的にこの接続を閉じるまで残ります。

    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

同じコマンドを同時に両端に送信するには...

2
F. Hauri

catを使用してすべてのファイルを連結し、それらをsshにパイプすることができます。

cat command1 command2 command3 | ssh root@Host 'bash -s'
1
Barmar