やっつけな日常(16) スマホでGo!じゃない。「外部コマンドを実行」でコケたトホホな理由

Joseph Halfmoon

スマホでGo言語を動かす筈が、Ubuntuで実行してます。やっぱりキーボードが使える方がお楽。そうはいっても同じソースがスマホでもパソコンでも走るのでご勘弁。さて今回は、ツマラヌ間違いで上手く動かなかった件を反省。よく見れば直ぐに気が付く話、トホホ。

「スマホでGo」では、簡単に fmt.Printを使って画像出力ができる、ということで調子に乗ってUnix/Linux式のPBMおよびPPMフォーマットの画像出力を使ってきました。主にフラクタル、カオス系の図形(昔は人気だったやつら)などを描いて一人悦にいっておったのですが、1つ不満が。

PBM、PPM画像はUnix/Linux系の画像ビューワーでしか見られない

PNGやJPGフォーマットの画像のようにスマホのアプリで表示できませぬ。そこで定番の ImageMagick をインストール、convert コマンドで、PBM、PPMをPNGなどに変換してました。いちいち手入力メンドイ。特にスマホでは。

このルーチンワーク、自動化するじゃん

そうですね。Goの描画プログラムの末尾で convert コマンドを呼んでソースとなるPBM/PPMファイル名と、デスティネーションのPNGファイル名などを渡してやればOKと。そこで以下のGo言語のサンプルページを参照させていただきました。

Go by Example: Exec’ing Processes

なんだ、簡単じゃん、直ぐにできそう。なお、外部プログラム起動のためのGoのAPIのドキュメントは以下に。

syscall

以下は、上記のExampleページのソースをほぼほぼパクリで作成したconvertコマンドの起動サンプルプログラムです。こいつを本物の描画プログラムの末尾にガッチャンコすれば良いっと。

package main

import (
  "os"
  "os/exec"
  "syscall"
)

func main() {
  binary, lookErr := exec.LookPath("convert")
  if lookErr != nil {
    panic(lookErr)
  }
  args := []string{"convert", "s.ppm", "s.png"}
  env := os.Environ()
  execErr := syscall.Exec(binary, args, env)
  if execErr != nil {
    panic(execErr)
  }
}

しかしね、最初、トホホな理由で上手く動かなかったんでありますよ。しばらく原因わかりませんでした。

まず以下の行で convert コマンドの実行ファイルの在り処(パス)を調べています。binaryの中にconvertを起動するためのパスが入ります。(当然ノーエラーのとき)

binary, lookErr := exec.LookPath("convert")

上記で binaryの在り処が分かっているというのが伏線になりました。続いて convert コマンドに渡す引き数2つ、元のファイル名と変換先のファイル名を以下のようにして生成。

 args := []string{"s.ppm", "s.png"}

あと環境envについてはGoのAPIそのままを呼んでいるだけなのでこれで

syscall.Exec(binary, args, env)

が動く筈っと。しかし、動きませぬ。動作を観察するにちゃんと convert コマンドの実体オブジェクトは動きだしている感じがします(手元のシステムでは、リンクを2回だったか3回だったか辿り、長いお名前の実体オブジェクト・ファイルが起動されてました。ここは問題なし)

しかし、引数が正常にわたってないです。あまつさえ、良く見ると convert コマンド自体が印字しているらしいエラー、自分が convert というお名前だと知らないみたい。

そうでした。argsの最初の要素、実行ファイル名じゃありませんか。cのargvも最初は自分の御名前だよね。勿論、Exampleのソースもそうなってます。自分が真似っ子して convert に適用したときに「忘れて」いた。それだけ。トホホ。

以下のように引数リストを修正。直ぐに正常動作。

 args := []string{"convert", "s.ppm", "s.png"}

なんだかな~。オオボケ。やっつけ過ぎるよ。

やっつけな日常(15) スマホでGo!じゃない。ヒルベルト曲線 へ戻る

やっつけな日常(17) スマホでGo!GoのポインタはCとは違うケド、ちょっとだけよ へ進む