忘れたときに備えた記録

トップ 最新 追記
2005|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|11|12|
2009|01|02|03|04|05|06|10|12|
2010|06|07|08|12|
2011|07|09|
2012|09|11|
2013|02|03|09|
2015|10|11|
2016|01|08|11|
2017|02|08|10|
2018|11|

2009-03-02(Monday)

screenセッションが残っていたら、そっちにattachする方法

といっても、

$ screen -xR

で済ますとか、そういう話ではありません。

背景

普段Ubuntu Desktopをインストールしたパソコンを使っているのですが、これにリモートからsshで入る事があるのです。大抵はちょっとした作業をするだけなんですが、時々、時間がかかる処理で結果を確認したいものとか、途中で接続が切れたら困る作業とかをする事があります。apt-get upgradeとかですね。

そういう場合にscreenを使うのですが、~/.profileとかに

screen -xR

と書いてログインしたときに常にscreenを動かすのはちょっと煩わしいので、必要なときだけ手動でscreenを起動するようにしています。

さて、リモートのマシンでscreenを使って作業を始めて、時間がかかりそうなのでdetacheして、とすると、そのまま忘れてしまう恐れがあります。「screenセッションが残っているのであとで確認する」とかのタスクをGTDで作ってしまっても良いのですが、次回のsshログインやそのマシンのデスクトップでterminalを起動したときに、自動的にscreenが起動してくれれば便利なわけです。ただし、普段は起動しなくて良い。自動で起動してほしいのはscreenセッションが残っているときだけ、というわけです。

screenセッションが残っているか調べる方法

screenのマニュアルを調べると、-lsオプションで調べる事が出来ると分かりました。こんな感じです。

~$ screen -ls
No Sockets found in /var/run/screen/S-hiraku.

セッションが残っていると、こうなります。

~$ screen -ls
There is a screen on:
        25135.pts-1.shako       (2009年03月03日 03時13分42秒)   (Attached)
1 Socket in /var/run/screen/S-hiraku.

これを使って、最初はシェルスクリプトで

if [ -n "`screen -ls | egrep -i 'sockets? in'`" ]

としていましたが、その後、プログラムのリターンコードでも判別する事が出来るとわかりました。次のような意味になっています。

  • 9 : セッションなし
  • 10 : attachできないセッション
  • 11 : attachできるセッションがある

これを使うと

screen -q -ls
if [ $? -ne 9 ]; then
   exec screen -x
fi

と書けるようになります。これを~/.bashrcに書いておけば、リモートでscreenセッションを作った後で、そのマシンのデスクトップに直接ログインした後でgnome-terminal等を開くと、自動的にscreenが起動するようになります。ただし、このままだとscreenで新しいウィンドウを開いたりしたときにもこの処理が実行されてしまい、「screenの中でscreenを起動しようとしている」という警告が出てしまいます。

screenの中にいるかどうかを判定する方法

これまたscreenのマニュアルにあったのですが、環境変数 STY を使って、今いるのがscreenの中かどうかを調べる事が出来ます。screenの外では、(少なくとも手元の環境では) STY は未定義です。なので、先程の自動起動処理は

screen -q -ls
if [ $? -ne 9 -a -z "$STY" ]; then
        exec screen
fi

と書く事が出来ます。

ついでにkeychainも

screenを開いたときにはkeychainも起動して、すべてのscreenセッションを閉じたときにはkeychainによるssh-agentも終了するようにしました。

まず、screenを起動する用のスクリプトを作ります。名前はrun_screenとしました。

#!/bin/sh
screen -q -ls
if [ $? -eq 9 ]; then
        screen
else
        screen -x
fi
/usr/bin/screen -q -ls
if [ $? -eq 9 ]; then
        keychain -k mine -q
fi

これをPATHを通したディレクトリに入れておいて、~/.bashrcに次の記述を入れておきます。

screen -q -ls
if [ $? -ne 9 -a -z "$STY" ]; then
        exec ~/hg/misc/bin/run_screen
fi
if [ -n "$STY" ]; then
        eval `keychain --eval -q`
fi

alias screen="~/hg/misc/bin/run_screen"

これで、

  • screenと打つとscreen(を起動するスクリプトであるrun_screen)が起動する
  • screenが起動したときにはkeychainも実行される。これがssh-agentが起動したり、すでに起動しているなら流用したりしてくれる
  • screenセッションが残っている状態で新しいbashを起動する(sshログインとか新しいターミナルを開くとか)と、自動でscreenが起動してセッションにattachする
  • すべてのscreenセッションが終了すると、keychainで起動したssh-agentも自動で終了させられる

という処理が出来ます

ファイルの中で、Emacsのメジャーモードを指定する

bashの設定ファイルをいろいろいじっていて、「先頭に #!/bin/bash がないファイルを Emacsで開いたときに、自動で Shell-Script-modeになってほしい」という状況が起こりました。

「tDiaryのソースに何かコメントを書いておくと、Emacs起動時に自動的に3タブになる」という話を以前どこかで見かけた気がしてググったらEmacsを3タブで使う設定 - 32nd Diary(2008-05-10)が見つかったのですが、似たような方法でメジャーモードも変えられないかと思ってさらに調べたら、File-local Variables in Emacsというページが見つかりました。

で、今はこんな記述を当該ファイルに入れています。

# Local Variables:
# mode: Shell-script
# End:

まぁ実際は、不要でも先頭行に

#!/bin/bash

と書いておけばそれで済んじゃうんですが、せっかく調べたのでメモしておきます。

本日のツッコミ(全1件) [ツッコミを入れる]

_ ひらく [テストです]


2009-03-20(Friday)

specでプロファイリング

この間たまたま見つけたのですが、specの出力形式を指定するオプション'-f'に'profile'というものがありました。いつから追加されていたんでしょ

こんな感じでテストにかかる時間を表示してくれます。

修正前

:~/local/mercurial$ rake SPEC_OPTS="-cf profile"
(in /home/hiraku/local/mercurial)
Profiling enabled.
.........................


Top 10 slowest examples:
1.8614330 Mercurial::Repository#pull with revision
1.7498210 Mercurial #clone with revision
1.4745410 Mercurial::Repository#pull #id
0.9761460 Mercurial::Repository#pull default revision is tip
0.2236100 Mercurial #clone
0.2183990 Mercurial #find should return array of repository in given path
0.1543410 Mercurial::Repository#cloned_from should return nil if [paths] default not exist
0.1448860 Mercurial::Repository #new
0.1382820 Mercurial::Repository #path
0.1354290 Mercurial::Repository #exec should call @hg.exec with -r #path

Finished in 7.814099 seconds

25 examples, 0 failures

修正後

:~/local/mercurial$ rake SPEC_OPTS="-cf profile"
(in /home/hiraku/local/mercurial)
Profiling enabled.
...........................


Top 10 slowest examples:
0.1601340 hg command line 'id' should print revision of working directory
0.1453510 hg command line should warn 'abort: unknown revision' when it is given invalid revision
0.0106090 Mercurial::Repository #exec should call @hg.exec with -r #path
0.0052730 Mercurial #find should return array of repository in given path
0.0048770 Mercurial::Repository#pull with revision
0.0044350 Mercurial #repository
0.0038240 Mercurial#clone should optionally accept revision to clone
0.0037720 Mercurial#clone should call exec with 'clone'
0.0031890 Mercurial::Repository #path
0.0031820 Mercurial::Repository #add_hgrc

Finished in 0.405065 seconds

27 examples, 0 failures

こんな具合にスピードアップの実感が掴めてちょっと楽しいです。

Tags: RSpec

追記

「いつから追加されていたんでしょ」じゃなくて、調べてみればいいのですな。

というわけでRSpecのgemに入ってるHistory.txtを見てみたら、1.1.0-RC1の段階で追加されたようです。