まだプログラマーですが何か?

プログラマーネタ中心。たまに作成したウェブサービス関連の話も https://twitter.com/dotnsf

タグ:screen

UNIX コマンドの1つである screen はターミナル内で使えるとても便利なコマンドです。僕も時間のかかるバッチ処理などを行う際に、
 (1) まず screen
 (2) screen セッションの中でバッチ開始
 (3) セッションをデタッチ(Ctrl A + Ctrl D)
とすると、(3) の後にログアウトしてもバックグラウンドでバッチ処理を実行し続けてくれ、再ログイン後に screen -r コマンドを実行することで再度その処理を実行していたセッションに再接続(アタッチ)することができるのです:
$ screen -r

そこで処理が終わっていれば結果も確認できるし、まだ終わっていないようであれば、再度デタッチしてログアウトして・・・とても重宝しています。

さて、上記のように明示的にデタッチしてからログアウトする場合はよいのですが、通信状態がよくない場合などに
 (1) まず screen
 (2) screen セッションの中でバッチ開始
 (3) セッションをデタッチする前に通信が切れるなどして強制終了
してしまうことがあります。こうなるとそのセッションは実行中のままにはなりますが、再度ログインしてから再接続することはできなくなってしまうのです:
$ screen -r
There is a screen on:
        nnnn.pts-0.xxxxx   (Attached) 
There is no screen to be resumed. エラーメッセージが出てアタッチできない
$

そんな不可抗力な現象に遭遇した場合、以下の方法で再接続することができます。

まずは現在実行中の screen プロセスを確認します:
$ ps aux|grep pts|grep sshd
kkimura   1111  0.0  0.2   ****  **** ?        S    18:42   0:00 sshd: kkimura@pts/0
kkimura   2222  0.0  0.2   ****  **** ?        S    20:47   0:00 sshd: kkimura@pts/9
kkimura   3333  0.0  0.0   ****   *** pts/9    S+   20:49   0:00 grep -r sshd

↑一番下のプロセスは grep なので関係なし、その上の pts/9 は現在のセッション。一番上の pts/0 のセッションが残ってしまっているためにアタッチできなくなっています。

というわけで pts/0 のセッション(PID が 1111 のもの)を kill します:
$ kill 1111

これで再度アタッチできるようになります:
$ screen -r


UNIX/Linux 系 OS 用の仮想端末マネージャーである screen コマンド。以前に紹介した tmux に似てるけど、screen は多くのケースで標準導入されているので、ビルドとかなしにそのまま使えることが多いです。

というわけで、概要と使い方のメモ:

【screen コマンドとは?】
- 1つのターミナル上で、仮想的に複数の端末を同時にオープンして作業するツール。
- 仮想端末が開かれた状態を保ったままターミナルをログアウトできる。後から再度ターミナルでログインして、screen を呼び出すことで仮想端末の状態に復帰できる。
- 1つのターミナルの画面を上下に分割して、複数の端末を同時にアクティブにして(切り替えながら)操作できる。


【screen コマンドの使い方】
screen 起動
# screen
screen 内で新しい仮想端末を開く
[ctrl]+a c
screen 内で動いている仮想端末の一覧表示
[ctrl]+a w
screen 内で動いている別の仮想端末に移動する
[ctrl]+a n または [ctrl]+a [space] 昇順移動 [ctrl]+a p または [ctrl]+a [del] 降順移動 [ctrl]+a 数字 (数字)で示される仮想端末に移動 [ctrl]+a [ctrl]+a 直前に使っていた仮想端末へ戻る
現在開いている仮想端末を閉じる(キル)
[ctrl]+a k
現在開いている仮想端末をサスペンド状態にして閉じる(デタッチ)
[ctrl]+a d
screen 内でデタッチ状態で動いている仮想端末の一覧表示
# screen -ls (ここで PID が確認できる)
screen 内でデタッチ状態で動いている仮想端末に戻る(アタッチ)
# screen -r PID
デタッチせずに screen を終了する
[ctrl]+a \
起動中の screen をバックスクロールモードにする
[ctrl]+a [
バックスクロールモードでテキストコピー
カーソルを始点に移動させて [space] または [enter] カーソルを終点に移動させて [space] または [enter]
コピーしたテキストのペースト
[ctrl]+a ]
画面を上下2分割
[ctrl]+a S
画面分割後にフォーカス画面を変更
[ctrl]+a [tab]
画面分割をやめる
[ctrl]+a Q

【実際の使い方】
一度実行すると、処理完了まで1日程度かかるコマンド(# php test.php)があるとします。
これをサーバー上で実行して、一度デタッチして(バックグラウンドで処理を続けて)からサーバーとの接続を切断し、翌日サーバーに再度ログインして結果を確認する。
(ssh や telnet でサーバーにログイン)

# screen screen 実行(この時点で仮想端末0が実行される)

[ctrl]+a c 新しい仮想端末1を作成して移動

# php test.php 処理実行開始・・・・

[ctrl]+a d 処理実行中の仮想端末をデタッチ(この時に screen からも抜ける)

# screen -ls デタッチした処理の PID を確認( XXXX だったとする)

# exit (サーバーからログアウト)

  :
  :
  :

(翌日、再度 ssh や telnet でサーバーにログイン)

# screen -r XXXX 前日デタッチした仮想端末をアタッチ

(処理が完了していたらそのまま続きの作業を行う。まだ完了してなかったら再びデタッチして完了を待つ)







このページのトップヘ