雑文発散

«前の日記(2014-01-14) 最新 次の日記(2014-01-16)» 編集
過去の日記

2014-01-15 [長年日記]

[Emacs] Emacs の call-process-shell-command と shell-command の違いと helm-gtags

GNU global によるタグ検索を Emacs + helm から利用するための helm-gtags.el という拡張がある。これが TRAMP 環境だとうまく動かないので、自前で少しいじって使っている。

具体的には、外部コマンドの実行部分を call-process-shell-command から shell-command へ置き換えている。

例えばこんな感じ。

  • オリジナル
(call-process-shell-command "global -p" nil t)
  • 修正版
(shell-command "global -p" t)

パッと見で分かるとおり、どちらも global という外部コマンドを実行している。引数の指定により、どちらもコマンド実行結果をバッファに書き出すようになっている。

それであれば、わざわざ call-process-shell-commandshell-command へ書き換えなくとも良いのではないか?と思うところなのだが、この2つのコマンド、ファイルがローカルにあるか、リモートにあるかで挙動が変わる。

テスト用に次のような関数を作ってみた。uname -a コマンドを実行するだけの簡単なもの。

(defun test-call-process-shell-command()
  (interactive)
  (call-process-shell-command "uname" nil t))

(defun test-shell-command()
  (interactive)
  (shell-command "uname" t))

まず、これらの関数をローカル(Mac OS X)の test.txt を読み込み、その中で M-x を使って実行してみる。

 # test.txt in OS X Mavericks

 # M-x test-call-process-shell-command
 Darwin

 # M-x test-shell-command
 Darwin

どちらの関数の結果も Darwin が返ってきている。

次に TRAMP を使ってリモートサーバ(Debian wheezy)にある test.txt を読み込み、同じように実行してみる。

 # test.txt in Debian wheezy

 # M-x test-call-process-shell-command
 Darwin

 # M-x test-shell-command
 Linux

test-shell-command の実行結果が Linux となった。

test-shell-command の実体は、shell-command 関数を実行しているだけだなので、つまりこれは「shell-command の引数のコマンドがリモートサーバで実行された」ことを表している。

しかし、shell-command がリモートサーバを考慮して実装されているのかと言うと、そうではない。本来の shell-command 関数は、call-process-shell-command と同じように Emacs が稼働中のマシンでコマンド実行する作りになっていた。

じゃあ、なんでリモートサーバで外部コマンドが実行されたのが疑問だったのだが、結局のところ TRAMP が shell-command を差し替えて実行していた。

tramp.el 内に tramp-handle-shell-command 関数があり、こいつが shell-command と同等の処理をリモートサーバ上で実行する処理を行なっていた。

TRAMP そのものの挙動の理解が足りていないので、何をやっているのか分からない部分も多いのだけど、いろいろゴニョゴニョやって実現させているようだ。

つまり何が言いたいのかというと、helm-gtagscall-process-shell-commandshell-command に変えてしまえば TRAMP にも優しくなるよと思うのだけど、その他の影響が存在するのかがいまひとつ把握しきれずに提案(pull request)が投げられなくてモヤモヤしている。

本日のツッコミ(全1件) [ツッコミを入れる]
yewton (2014-01-22 21:15)

こんな感じでしょうか?<br>https://github.com/yewton/emacs-helm-gtags/commit/d626d0247d81a067ae661bad2c69045f2d1936b4<br><br>とりあえず pull request 出してみちゃおうかなと思ってます。。