2008年11月27日木曜日

GNU screen で仮想端末。処理をほったらかしにして切断、さあ帰ろう

先日、全力でCPU負荷をかけているサーバにリモートシェルからMySQLのレコードを数十万行流し込むという用事があった。
作業してた人は、sshクライアント落とせないので 「PC落とせない=帰れん」 となり、少々悩んで結局PCをつけっぱなしで帰った。
 

これが自分の身に降りかかったら とても嫌 だと思い、そうなった場合の対策を探したところ、GNU screen という結構由緒正しい仮想端末ソフトがヒット。
 
これは使える、、、知らなかったのは不覚だ。ちょっとさわりを書いてみる。
(追記)突然の回線切断でも大丈夫、繋ぎなおしたら作業中の環境復活OK、と追記しとく。
 
 

screen のデタッチ、アタッチについて簡単に説明


勝手に終わらないコマンドとして適当なもの、たとえばTOPを実行しているとした場合。
 

×Screenがないとき
TOPコマンドはsshクライアントからつないだ仮想端末(例:xterm)を制御端末として動く。
sshクライアントを終了するとTOPコマンドの制御端末がなくなるのでTOPコマンド終了ー。
 

○Screenがあるとき
sshクライアントからつないだ仮想端末(例:xterm)でscreenコマンドを使用すると、新たな仮想端末(screen)ができる。
screenからTOPコマンドを実行すると、当然制御端末は screen になる、そして screen は起動時の制御端末 - xterm が終了しても独立して動く機能がある。
ということで、sshクライアントを終了しても screen は配下のTOPコマンドを生存させたまま残ることが可能。
(追記) これは別の表現で言うと突然xtermの接続が切れても大丈夫、ということ。
 
 

表現とかちと怪しい部分もあるが大体こんな感じ、
詳しいことは下記サイトとかがいいのかな?

screenのススメ
http://www.dekaino.net/screen/


screenの理解ならここはとても参考になります。ただ、エスケープキャラクタは「Ctrl+a」のままでもいいと思う。
 
 

一通り実際やってみる


yum でも cvsよいのでscreenをインストールしよう。cvs のほうが縦分割ができてお得か。
 

[caption id="attachment_1074" align="alignnone" width="500" caption="画像:puttyでsshログイン"]画像:puttyでsshログイン[/caption]
早速screenコマンドを叩いてみる、クライアントは putty を使った。
 

[caption id="attachment_1075" align="alignnone" width="500" caption="画像:screen起動直後"]画像:screen起動直後[/caption]
タイトルバーのところに「screen 0」 というのが出てきた。今は仮想端末screenの0番を使っているよという意味だ。準備OK。
 
 

コマンドを実行したままで screen をデタッチ


screen上で適当にコマンドを実行して、そのままscreenを切断します。
ちなみにscreen制御用のコマンドはまずエスケープ(デフォルトではCtrl+a(^a と書いたり))してからコマンド入力します。とりあえずデタッチは「Ctrl+a → D(大文字)」
 

[caption id="attachment_1076" align="alignnone" width="500" caption="画像:screenで画面分割、コマンド実行"]画像:screenで画面分割、コマンド実行[/caption]
とりあえずscreenの画面分割機能を使って、ping, vmstat, top と実行してみた。
0番のping シーケンス番号が目安になるかな、
 
そしておもむろに デタッチ「Ctrl+a → D(大文字)」
 

[caption id="attachment_1077" align="alignnone" width="500" caption="画像:「^a + D」でscreenをデタッチ"]画像:「^a + D」でscreenをデタッチ[/caption]
screen実行前の仮想端末に帰ってきた、一回ログアウトする。
 
 


デタッチしたscrennに後日アタッチして、続きをやる


とりあえず「screen -ls」で今動いているscreenのリストがとれる。目的のものに「screen -r {プロセスID(1つしかなければ省略可)}」 でアタッチすればいい。
 

[caption id="attachment_1078" align="alignnone" width="500" caption="画像:接続しなおして、screenのリスト"]画像:接続しなおして、screenのリスト[/caption]
リストがとれたのでアタッチする。
 

[caption id="attachment_1079" align="alignnone" width="500" caption="画像:アタッチした"]画像:アタッチした[/caption]
screen 0番につながったのがわかる、ping健在。
他のコマンドはどうだろうか。
 

[caption id="attachment_1080" align="alignnone" width="500" caption="画像:screen上の分割リスト"]画像:screen上の分割リスト[/caption]
screen内の画面リストを出してみる、名前は任意に変えることができるのでここではわかりやすい名前を付けている。
それぞれに切り替えてみるとコマンド実行が継続されていることがわかる。
 


[caption id="attachment_1081" align="alignnone" width="500" caption="画像:デタッチ前の状況が保たれている"]画像:デタッチ前の状況が保たれている[/caption]
切断前の状況再現(継続中)もOK。ヒストリなどもちゃんと継続している。
いやあこれは便利だ。
 
 

次は分割?


screen は正直機能が多くてまったく紹介しきれないが、まずはこのデタッチ・アタッチを知っておくと便利なので各サーバに導入しておきたい。
 

余談として、プロンプトに($TERM) を表示するようにすると区別がついていいかも。
「PS1='[\u($TERM)@\h \W]\$ '」 というようにしておくと、
[sawano(xterm)@myserver ~]$
[sawano(screen)@myserver ~]$
こんな感じになってscreen使用中かどうかわかる。
 

今度は分割も記事にしたい、打鍵で混乱するからそのへん消化したいんだよね。