ラベル launchctl の投稿を表示しています。 すべての投稿を表示
ラベル launchctl の投稿を表示しています。 すべての投稿を表示

2013年1月14日月曜日

Macがスリープした後のSynergyの挙動を直す

前回の記事で書ききれなかった別の問題と解決法について書きたいと思います。

Windows側のマウスのスピードが速すぎる時がある


この現象が起きるのは、Macがスリープしてその後スリープ解除された場合です。スリープ解除後に、マウスをWindowsの画面に持って行くとマウスの移動速度が速すぎて使いづらいのです。
これは、Synergyの設定では対処できないようです。
これの対処には、Sleepwatcherというプログラムを使いました。
Sleepwatcherは、Macがスリープしたりスリープ解除(ウェイク)したりするのを監視して、そのタイミングであらかじめ指定してあるコマンドを実行するプログラムです。
Sleepwatcherは、MacPortsからインストールできます。また、作者のウェブサイトからもダウンロード、インストールできます。
私は、インストールにはMacPortsを使いました。

MacPortsでのインストール

MacPorts自体のインストールの説明は長くなりますので、既にインストールされていることを前提にします。以下のコマンドで簡単にインストールできます。

$ sudo port install sleepwatcher

実行後、sleepwatcherは /opt/local/sbin にインストールされます。

ダウンロード

作者のサイト http://www.bernhard-baehr.de/ からダウンロードできます。私はMacPortsでインストールしたのでプログラムのソースコードは不要だったのですが、設定ファイル(Ploperty Listファイル)の参考にダウンロードしました。

Property Listファイルの作成

SleepwatcherもSynergyと同様にlaunchctl経由で実行・停止の制御をします。そのためには、Property List (plist)ファイルの作成が必要です。一から作成するのは間違いが入る可能性も高くなるので、ダウンロードしたアーカイブファイルに含まれている plistファイルを参考にして作りました。
以下にその内容を示します。基本的には、ユーザ単位でのスリープ監視にしています。


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
        <key>Label</key>
        <string>org.macports.sleepwatcher-localuser</string>
        <key>ProgramArguments</key>
        <array>
                <string>/opt/local/sbin/sleepwatcher</string>
                <string>-V</string>
                <string>-s ~/.sleep</string>
                <string>-w ~/.wakeup</string>
        </array>
        <key>RunAtLoad</key>
        <true/>
        <key>KeepAlive</key>
        <true/>
</dict>
</plist>


上記の内容を、~/Library/LaunchAgents/org.macports.sleepwatcher-localuser.plist として保存します。簡単な説明は以下のようです。
ProgramArguments keyにプログラム名と引数の並びをarrayとして定義しています。
-Vオプションはverboseオプションで詳細なログを出力します。
-sオプションでスリープする時に実行されるプログラムを指定しています。
-wオプションでウェイクアップした時に実行されるプログラムを指定しています。
どちらもシェルスクリプトにしています。

次に、.sleepと.wakeupの内容を説明します。
.sleepは #!/bin/sh だけの行で実質的に空ファイルです。
.wakeupは、Synergyを再起動するシェルスクリプト(restart_synergy.sh)を記述しています。

#!/bin/sh
$HOME/bin/restart_synergy.sh

restart_synergy.shの中身は次のようになっています。


#!/bin/sh

PLIST=$HOME/Library/LaunchAgents/org.synergy-foss.org.synergys.plist

if launchctl list | grep -q synergys ; then
    #echo unloading `basename $PLIST` ... 1>&2
    launchctl unload $PLIST
    sleep 1
fi

#echo loading `basename $PLIST` ... 1>&2
launchctl load $PLIST


launchctl listでsynergysが実行されているかどうかを確認し、実行されている場合は一旦停止してからsynergysを再起動します。もともと実行されていなければすぐsynersysを起動します。
また、これらのスリープ、ウェイクアップ用スクリプトファイルに実行用パーミッションを付けておきます。

$ chmod a+x .sleep .wakeup

最後に、launchctlコマンドで起動します。

$ launchctl load ~/Library/LaunchAgents/org.macports.sleepwatcher-localuser.plist

Macをスリープ、解除してWindows側の画面にマウスを持って行ってマウスの速度が通常通りになっていれば成功です。

2013年1月13日日曜日

Synergyを自動起動するようにする

Synergyを設定して以前より便利になりました。でも、だんだん直したい点も出てきました。以下に挙げます。
  1. Windowsの左画面が遠い。
  2. Synergyのアイコンが2個表示される。
  3. ログイン時に自動起動したい。
  4. ログメッセージが多い。
順番に、説明と対策を書いていきます。

1. Windowsの左画面が遠い

Synergyからは、Windowsの画面は1つあるようにしか見えないのですが、実際は24インチモニタが2台並んで接続されています。そのうちの右側のモニタをMacとWindowsで共用しています。ですので、Macのモニタの画面の左端からWindowsの左端のスタートメニューまで行こうとすると、距離が1920 x 2あるので移動が大変です。(何か設定があるのかもしれませんが)

実際の見た目は以下のようですが、
#   mon.1      mon.2     MB Air
# +--------+ +--------+ +-------+
# |Win7    | |MBA/Win7| |MBA    |
# |        | |        | |       |
# +--------+ +--------+ +-------+

Synergyからは以下のように見えます。

#   mon.1      mon.2      mon.2     MB Air

# +--------+ +--------+ +--------+ +-------+
# |Win7    | |Win7    | |MBA     | |MBA    |
# |        | |        | |        | |       |
# +--------+ +--------+ +--------+ +-------+


現状では、Synergyの設定を変えて、以下のようにMacのモニター2(メニューバーのある方)の下に、Windowsのモニタ1が来るようにしています。

# +--------+ +-------+
# |MBA     | |MBA    |
# |        | |       |
# +--------+ +-------+
# +--------+ + - - - -+
# |Win7    | |Win7    |
# |        | |        |
# +--------+ + - - - -+
物理的には、MBAの左側画面とWin7の右側が共用されていて、普段はMacの画面が表示されているわけです。ちょっとわかりづらいですかね。Mac上でマウスを下に持って行くと、Windowsの画面の上からマウスが下りてきます。これで、マウスの大移動をする必要がなくなり、楽になりました。


2. Synergyのアイコンが2個表示される

Dock上や、command + tabキーを押した際に、Synergyのアイコンが2個表示されています。
Synergyはいったん設定した後は、特に操作対象にはなりませんので、非表示でかまいません。
これには、アプリケーションファイルのパッケージを開き、その中のInfo.plistを修正します。
Info.plistをエディタで開いて、<dict>と</dict>で囲まれた領域に次の2行を追加します。

<key>LSUIElement</key>
<true/>

これで、Dock等にアイコンが表示されなくなります。また、注意点としてFinder上での起動操作等も出来なくなりますので、次の3, 4等の対策を行った後に変更するのがいいと思います。

3. ログイン時に自動起動したい
4. ログの出力が多い

Windows側のSynergyクライアントはログイン時に自動的に起動されます。Macでもログイン時に起動したいと思います。単純にSynergysのDockアイコンを「ログイン時に起動」と設定してもうまくいかなかったので、ちゃんとした方法を調べました。
まず、サーバの起動方法は、Synergyのwikiサイトをいろいろ調べると

$ synergys --config /path/to/synergy.conf

でコマンドラインから起動する方法が示してありました。また、Mac OS Xでは起動はlaunchdで行うのがよいとのことでした。このブログを書いている時点(1/13)では、サーバーのProperty List (plist)ファイルの例はまだなくソースコードを見てほしいという記述なっていました。
以下に現在使っているplistファイルの例を記載します。


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
          "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <!-- Mac OSX only: Copy this plist file into [~]/Library/LaunchAgents to start synergy server automatically. Make sure you change configuration file below -->
  <dict>
    <key>Label</key>
    <string>org.synergy-foss.org.synergys.plist</string>
    <key>OnDemand</key>
    <false/>
    <key>ProgramArguments</key>
    <array>
      <string>/Applications/Synergy.app/Contents/MacOS/synergys</string>
      <string>--no-daemon</string>
      <string>--debug</string>
      <string>NOTE</string>
      <string>--config</string>
      <!-- Replace this path with the path to your synergy configuration -->
      <string>/Users/your_user_id/.synergy.conf</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
  </dict>
</plist>


以上の内容を、
~/Library/LaunchAgents/org.synergy-foss.org.synergys.plist
として作成します。
注意点というほどではありませんが、次の点に注目してください。

  1. この例では、synergysはデーモンとしては起動せず通常のプログラムとして起動しています。
  2. --debugオプションにNOTEを指定して、ログファイル(/var/log/system.log)の出力を抑えています。これを指定しない場合、デフォルトはINFOのため、マウスが別のマシンの画面に出入りした場合や、クリップボードへのコピー、ペーストなどの際もログファイルに出力が出てきます。(synergys -hでhelpが見れます)
  3. --configオプションの引数で、confファイルを指定しますが、ここは好きな場所を指定してください。また、confファイル自体は、wiki等を参考に作成してもいいのですが、前の記事のようにSynergyから、FileメニューのSave configuration as... を選んで、自分のホームディレクトリの下に.synergy.conを保存するのが簡単だと思います。
Synergyから保存した時、バグかもしれませんが、confファイルのパーミッションにreadが付いていませんでしたので、修正してください。

$ less .synergy.conf
.synergy.conf: Permission denied

なんと、自分で作成したファイルなのに読めません。

$ ls -l .synergy.conf
--w-------  1 karuku  staff  737 11  9 11:48 .synergy.conf

あまり見たことのないパターンです。次のように修正してください。
$ chmod a+r .synergy.conf

ここまで準備が整った状態で、以下のコマンドでsynergysが実行されるよう指定します。
launchctl load ~/Library/LaunchAgents/org.synergy-foss.org.synergys.plist

ログインし直しても実行されるようです。
実行を止めたい場合は、以下のコマンドを使います。


launchctl unload ~/Library/LaunchAgents/org.synergy-foss.org.synergys.plist


これでログイン後の立ち上げなどは気にする必要がなく使えるようになりました。

ただ、ちょっとした問題として、Macのターミナルが最前面のアプリケーションになっていると、Windows側にマウスが入っていっても、キーボード入力がWindowsに渡らないという現象が起きています。また、その状態でWindowsのExplorer上でスクロールバーをマウスで操作するとターミナル側の行がセレクトされたりの現象も起きています。
また、Windows上にマウスが移動している場合も、Macの画面上にマウスポインターが現れたりしているようですね。通常は、Windowsの画面を見ているので気にならないとは思いますが。

最後に、次の記事にMacがスリープして解除された後にWindows上のマウスのスピードが速くなる現象の対処について書きたいと思います。

.MaxOSX/environment.plistからPATH変数が読まれないことへの対処 [一部修正]

去年(2012年)の前半頃(まだ、Snow Leopardを使っていた頃)のことですが、NerdToolやcrontabから起動しているスクリプトの一部が動かなくなっていることに気づきました。


暫定的な対応


動いているスクリプトと動かないスクリプトを見比べると、スクリプトをフルパスで起動したり、PATH環境変数を再設定しているものは動いていました。PATH変数が何らかの原因で設定されていないようです。とりあえずスクリプト内の動かなかったコマンドが起動できるようにPATH変数を修正して動くようにしていました。
例えばこんな感じです。

修正前
#!/bin/sh
site_check.sh

~/bin ディレクトリにsite_check.shスクリプトを置いていますので、HOME変数を追加します。HOME変数は設定されていました。また、このスクリプト内から/opt/local/binあるコマンドを起動できるようPATHに追加します。

修正後
#!/bin/sh
PATH=/opt/local/bin:$PATH
$HOME/bin/site_check.sh

原因と対応

PATH環境変数が設定されなくなった原因は、Mac OS Xのセキュリティアップデートでの仕様変更のように思われる(どこかで読んだ記憶がある)のですが、ソースを見つけられませんでした。Security Update 2012-002による変更で、ログインした際に、~/.MacOSX/environment.plist内のDYLD_*変数を読み込まないようにしたという記述はあるのですが、PATH変数については記載されていませんでした。[Appleのリンク]

対処については、

  1. アプリケーション内でのInfo.plistでのLSEnvironmentキーを設定する方法
  2. /etc/launchd.confを作成する方法
  3. 個別のアプリケーション毎にlaunchd.plist (ファイル名は別にするようです)を記述する方法

などがあるようです。

1)は、最も安全だそうですですが、アプリケーションのバージョンアップ等で変更を忘れてしまいそうです。また、アプリケーションによっては使えません。2)は、今までログイン時(個別ユーザ用)に設定していたものを、他ユーザにも影響がでるような形で設定するのは、若干抵抗があります。設定自体は、シェルスクリプトの記法に近く楽そうでよいのですね。
3)は、設定がアプリケーション単位で個別にできるのがよい点です。記述は若干面倒そうです。(使い方はLaunchDaemons (launchctl, launchd.plist) の使い方にわかりやすくとめられていました)

いろいろ考えた末、以下の方針にしました。方針というほど大げさなものでもないのですが。
  1. /etc/launchd.confを使用するが、設定は最小限にする。特に、セキュリティのため、自分のIDの書き込み権がある場所は指定しない。
  2. 個別のアプリケーション内の環境設定等で対応できるものは、そこで対応する。NerdToolのシェルスクリプト等、手間がかからないものも各スクリプトで設定する。
  3. 1.〜2.で対応できない場合、そのアプリケーション用のlaunchd.plistを作成し、ユーザ領域の~/Library/LaunchAgents で管理する
  4. アプリケーション内のInfo.plistを修正は、バージョンアップ時に修正を忘れたり管理が大変なため行わない。

/etc/launchd.confを設定する前に、現在のlaunchdのPATH設定を調べたところ、以下のようになっていました。
$ sudo launchctl getenv PATH
/usr/bin:/bin:/usr/sbin:/sbin

/etc/launchd.confは存在していないのでこれらは、デフォルトで設定されているのでしょう。また、/etc/pathsは以下のようになっています。

/usr/bin
/bin
/usr/sbin
/sbin
/usr/local/bin

自分のPATH設定に入っている$HOME/bin, /opt/local/bin, /opt/X11/bin, /usr/local/clamXav/binが含まれていませんが、これらはログイン後シェルで使うものが多いので/usr/local/binだけを設定することにしました。それ以外は、.bash_profile等で変更します。

/etc/launchd.confには、

setenv PATH /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin

と設定しました。また、/etc/pathsもそれに合わせて/usr/local/binを先頭に持ってきました。

また、crontabやNerdToolなどのシェルは、必要に応じてPATHを追加する方針ですが、現状既にそのように修正しているので基本的にはそのままです。PATHの追加が必要になるのは、ほとんどの場合、$HOME/bin か /opt/local/bin (MacPorts用のパス) です。

感想

environment.plistがサポートされなくなった背景には、Flashbackマルウェアの発生などMac OS Xでもセキュリティを厳しくする必要があるということが挙げられます。Mountain Lionでのsandbox化や承認されたアプリケーションしか基本的にはインストール・起動できないというのもその流れですね。もっと自由にしたいとか、いろいろ意見もあるようですが、今後ますますユーザレベルでも気を付けなければならないのではと思います。

[追記 2013/1/16 ] http://jvn.jp/cert/JVNTA13-010A/ によると、JAVAにまたセキュリティホールが見つかっていますね。注意したいものです。

2012年9月14日金曜日

locateデータベースを作る方法

このアプリケーションで開く その2の記事で、lsregisterコマンドをlocateコマンドで見つけることができると書きましたが、locateコマンドが使えないというか期待通りに動作しない場合があります。locateコマンドが使うデータベースがまだ存在しない場合です。
Snow Leopardの場合ですが、以下のように表示されます。
$ locate lsregister

WARNING: The locate database (/var/db/locate.database) does not exist.
To create the database, run the following command:

  sudo launchctl load -w /System/Library/LaunchDaemons/com.apple.locate.plist

Please be aware that the database can take some time to generate; once
the database has been created, this message will no longer appear.

簡単に訳すると、
locateコマンドが使うデータベース(/var/db/locate.database)がまだないので、sudo launchctl から始まっているコマンドで作ってと言っています。
これをターミナルで実行すればデータベースが作られます。1行で入力する必要があります。結構時間がかかると注意書きがあります。


launchctlコマンドが、直接locateデータベースを作っているのではなく、launchdというデーモンプロセス(システム上に常駐しているプロセス)に、/System/Library/LaunchDaemons/com.apple.locate.plistファイルに従って動作するように教えています。このファイル中で、locateデータベースを作るコマンドや実行するタイミングなどが定義されています。興味のある人は調べるといいと思いますが、データベースは1週間に一度土曜日の午前3:15に更新されるようです。最近インストールしたファイルはすぐ見つからない場合もあるかもしれません。