概要/背景
JewelCaseというちょっとしたDockerで動かすRailsアプリを作りました。
https://github.com/hakua-doublemoon/JewelCase
ここでDockerからホストにインストールされたVLCをCLI(SSH)で操作したかったのですが、net-sshだけだと難しかったのでこのnet-ssh-cli
を使いました。
詳細
ドキュメントなど
https://rubygems.org/gems/net-ssh-cli/versions/1.6.0
https://www.rubydoc.info/gems/net-ssh-cli/1.6.0
最新が「1.7.0 - February 01, 2021
」で、割と継続的にメンテナンスされているようなのが、これを採用した理由の1つでもあります。
基本的な使いかたと特徴
# ログインしてセッションを作る
@session = Net::SSH.start('172.18.0.1', user, password: passwd)
@cli = @session.cli(default_prompt: />|#{vlc_user}/)
# コマンド実行する
puts @cli.cmd("vlc --equalizer-bands \"3 2 1 0 1 2 3 4 5\" --equalizer-preamp 0")
ドキュメントにあるように、startはブロック(begin - end
)で使うこともできます。が、このgemの特徴はlong living CLI sessions
であり、ブロックで区切るのはもったいないです。
実際、上記のコードで作った@cli
は、このインスタンス変数を持つインスタンスが生きている限り(接続が切れない限り)使えます。net-ssh
だけだとコンソールを開きっぱなしにするのはちょっと頭を使うと思いますが、net-ssh-cli
だと簡単です。
注意点
net-ssh-cli
も完璧ではないです。
コマンドを打ったあとに応答がすぐ得られない場合がある
上のコードのように、基本的にはcmd
の応答でコマンドの結果を得られますが、確実ではないです。コマンドによっては応答を受け取れず、自分のコードが予期せぬ動作に入る場合があります。
そこで下記のように対応します。
@cli.write(cmd + "\n")
2.times do
sleep 0.2
puts @cli.read
end
write
メソッドでコマンドの実行だけ行い、出力はread
で得ます。コマンド結果の受け取りに失敗するような場合は、writeとreadの間にsleepを入れたり、再度read
をしてみたりします。
ここらへんの動作は場合によりけりな気がしますので、コードを試しに組んでから動作確認して考えるといいと思います。
なお、read
の結果が複数行になる場合も、戻り値は改行文字で結合された文字列オブジェクトであり配列にはなりません。(これはcmd
なども同じです)。