Mac: Linux側のシェルからsshでMac側のGUIアプリを起動する

Parallels Desktop for MacのおかげでUbuntu VMを快適に使えるようになりました。

後は、これまでMacのiTerm2などでは直接起動できたMacのGUIアプリを、Ubuntu VM側のシェルから起動できるようになれば、不足はもうありません。普通にMac側のシェルから開けば済むのですが、やってみたかったので。

具体的には、Gitのdiffを見るのに使っていたMergeDiff.appやSublime Text、GolandなどのIDEをUbuntu VM側から起動したいのです。

Ubuntu VMの中でLinux GUIのデスクトップ使うという手もありますが、ショートカットやら何やらでMacアプリの方が使いやすいし、少しでも軽くなるようUbuntuのデスクトップ環境を殺したので、今さらLinux GUIに戻したくありませんでした。

Sublime Textだけなら、rsubというパッケージをインストールすればVMからホストMacのSublime Textを起動できるのですが、Sublime TextをあらかじめMac側で起動しておかないと動いてくれないのが残念です。

当初AppleScriptをssh経由で実行しようと試行錯誤しましたが、最終的には素直にVMからMacにssh接続してbashスクリプトを送り込むだけでできました。

環境

  • macOS: Mojave
  • Linux: Ubuntu 18.04.1 LTS
    • (Parallels Desktop for Mac Home Edition上で動作)

以下、macOSのホスト名はtori、Ubuntu VMのホスト名はparaubuとなっています。

1. Mac側の設定

1. Macをsshサーバーにする

これは実はmacOSの機能だけでできます。システム環境設定 > 共有を開き、リモートログインをオンにし、自分のユーザーだけにアクセスを許可します。

2. Ubuntu VMをマウント

別記事「Mac: ssh接続先をsshfsとosxfuseでマウントする」を元に、macOSからUbuntu VMのディレクトリをマウントしておきます。

ここではmacOS側の~/paraubu/ディレクトリにUbuntu VMの/home/hachi8833/をマウントするようにしました。

3. ssh鍵の設定

Ubuntu VMからMacにパスワードなしで接続できるよう、鍵を設定します。

鍵は既にUbuntu VM上で生成済みのものを使いました。生成していない人はやっておく必要があります。

生成済みの鍵を、Ubuntu VMからMacにscpでコピーします。ユーザー名やホスト名は各自に合わせてください。

# Ubuntu VM側
$ scp ~/.ssh/id_rsa.pub hachi8833@tori:~/.ssh/temp_ssh

続いてMac側で鍵を設定します。パーミッションも適切に設定しないと効きません。

# Mac側
$ cat ~/.ssh/temp_ssh >> authorized_keys
$ chmod 600 authorized_keys
$ rm -rf temp_ssh

2. Ubuntu VM側の設定

4. /etc/hostsの設定

ついでに、Ubuntu VMから名前でMacにアクセスできるよう、/etc/hostsファイルにMacのIPアドレスを追加します。

# Ubuntu VM側
$ sudo vim /etc/hosts

追加するMacのIPアドレスは、Mac側でifconfigしてvnic0(Parallels Desktopの共有ネットワーク)のIPアドレスを使いました。

# Mac側
$ ifconfig

【略】
vnic0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
    options=3<RXCSUM,TXCSUM>
    ether xx:xx:xx:xx:xx:xx
    inet 10.xxx.xxx.xxx netmask 0xffffff00 broadcast 10.xxx.xxx.xxx
    media: autoselect
    status: active
【略】

5. /etc/ssh/ssh_config

ここまででだいたいOKなのですが、以下の小さなエラーが毎回接続時に表示されて邪魔でした。

tar: command configuring default locale

いろいろ調べると、Ubuntu VM側の/etc/ssh/ssh_configファイルに以下の記述があるのが原因であることがわかりました。

# Ubuntu VMの/etc/ssh/ssh_config

Host *
【略】
SendEnv LANG LC_*

このSendEnv LANG LC_*をコメントアウトすることでエラーは表示されなくなります。

参考: ユーザのロケール設定方法 | server-memo.net

Ubuntu VMからMacのGUIアプリを起動する

後はヒアドキュメントでMac側のアプリを起動し、マウントしたUbuntu VMディレクトリを参照させるだけです。

以下は、Mac側のSublime Text 3をsublコマンドで起動し、Ubuntu VM上の指定のディレクトリを開く場合です。

# Ubuntu VM側

ssh -t hachi8833@tori <<EOT
~/bin/subl ~/paraubu/
EOT

上でsshに-tオプションを付けているのは、接続時にPseudo-terminal will not be allocated because stdin is not a terminal.というwarningが毎回表示されるのを防ぐためです。

参考: sshで踏み台経由時のショートカット - Qiita

後は各自やりたいことに合わせてシェルスクリプト化するなど存分にカスタマイズしましょう。

以下は個人的に過ぎますが、Sublime Text起動用のシェルスクリプトです。Ubuntu VMの~/bin/以下に置いて使っています。

#!/usr/bin/env bash
# -*- coding: utf-8 -*-

## MacのSublime Textを起動
# set -eux

LOCAL=`hostname`
LOCAL_DIR=/home/$USER/
HOST=tori
HOST_DIR=/Users/$USER
HOST_APP=$HOST_DIR/bin/subl
TARGET=`readlink -f $1| sed -e "s:$LOCAL_DIR::"`
TARGET_DIR=$HOST_DIR/$LOCAL/$TARGET

if [ $# -ne 1 ]; then
  echo "指定された引数は$#個です。" 1>&2
  echo "実行するには1個の引数が必要です。" 1>&2
  exit 1
fi

if ! [ -e $1 ] || [ -d $1 ]; then
  echo "指定されたファイル名またはディレクトリ名は存在しません" 1>&2
  echo "存在するファイル名またはディレクトリ名を指定してください" 1>&2
  exit 1
fi

ssh -t -t $USER@$HOST -o LogLevel=QUIET 1>/dev/null <<EOS
~/bin/paramount  # Ubuntu VMをマウントする
$HOST_APP $TARGET_DIR
exit 0
EOS

自分でも泥臭いと思います。もう少し楽な方法があるといいのですが、ひとまずこれでうまく動いています😋。


参考: vimでリモート先のファイルをsshプロトコル経由で編集する | 俺的備忘録 〜なんかいろいろ〜

今のようにSublimeでVintageousとか半端するより、Vimに身を任せる方がいいんだろうかという気もちょっとしてきました。

関連記事

Mac: Parallels Desktop for MacでUbuntu Server LTS環境を構築する

Mac: ssh接続先をsshfsとosxfuseでマウントする

デザインも頼めるシステム開発会社をお探しならBPS株式会社までどうぞ 開発エンジニア積極採用中です! Ruby on Rails の開発なら実績豊富なBPS

この記事の著者

hachi8833

Twitter: @hachi8833、GitHub: @hachi8833 コボラー、ITコンサル、ローカライズ業界、Rails開発を経てTechRachoの編集・記事作成を担当。 これまでにRuby on Rails チュートリアル第2版の監修および半分程度を翻訳、Railsガイドの初期翻訳ではほぼすべてを翻訳。その後も折に触れて更新翻訳中。 かと思うと、正規表現の粋を尽くした日本語エラーチェックサービス enno.jpを運営。 実は最近Go言語が好きで、Goで書かれたRubyライクなGoby言語のメンテナーでもある。 仕事に関係ないすっとこブログ「あけてくれ」は2000年頃から多少の中断をはさんで継続、現在はnote.muに移転。

hachi8833の書いた記事

夏のTechRachoフェア2019

週刊Railsウォッチ

インフラ

ActiveSupport探訪シリーズ