非IT企業に勤める中年サラリーマンのIT日記

非IT企業でしかもITとは全く関係ない部署にいる中年エンジニア。唯一の趣味がプログラミングという”自称”プログラマー。

【Go言語】Pythonプログラムをクリック実行できるランチャーを作った

   

Go言語でPythonスクリプトを簡単に実行できるシンプルなランチャーの作ったので書き留めておきます。このランチャーは、ビルドされたGoの実行ファイルと同じファイル名を持つPythonスクリプトを実行します。これを使えば、PythonスクリプトとGoの実行ファイルを同じディレクトリに置くだけで、ユーザーはGoの実行ファイルをダブルクリックするだけでPythonプログラムを動かせるようになります。

package main

import (
	"bufio"    // 標準出力の読み取りに利用
	"fmt"      // エラー出力やログ出力に利用
	"os"       // 実行ファイルのパスやエラー出力に利用
	"os/exec"  // 外部コマンド(この場合Python)の実行に利用
	"path/filepath" // ファイルパスの操作に利用
	"strings" // 文字列操作に利用
)

func main() {
	// 自身の実行ファイルのフルパスを取得
	exePath, err := os.Executable()
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		return
	}

	// 実行ファイルのファイル名(例: out.exe)を取得
	exeName := filepath.Base(exePath)

	// 拡張子を取り除いたファイル名(例: out)を取得
	baseName := exeName
	if ext := filepath.Ext(exeName); ext != "" {
		baseName = strings.TrimSuffix(exeName, ext)
	}
	
	// 実行したいPythonファイル名を生成(例: out.py)
	pyFile := baseName + ".py"

	// "python out.py" というコマンドを構築
	cmd := exec.Command("python", pyFile)

	// Pythonスクリプトの標準出力をGoのプログラムで受け取るためのパイプを取得
	stdout, err := cmd.StdoutPipe()
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		return
	}

	// Pythonスクリプトの実行を開始
	// ※ この時点ではまだプログラムはブロックされない
	if err := cmd.Start(); err != nil {
		fmt.Fprintln(os.Stderr, err)
		return
	}

	// 標準出力を1行ずつ読み込むためのスキャナを作成
	scanner := bufio.NewScanner(stdout)
	// Pythonスクリプトの出力がなくなるまで、1行ずつ読み取ってGoの標準出力に表示
	for scanner.Scan() {
		fmt.Println(scanner.Text())
	}

	// スキャナでの読み取り中にエラーが発生していないかチェック
	if err := scanner.Err(); err != nil {
		fmt.Fprintln(os.Stderr, err)
	}

	// Pythonスクリプトの終了を待機
	// これにより、GoのプログラムはPythonの終了コードを受け取って終了する
	if err := cmd.Wait(); err != nil {
		fmt.Fprintln(os.Stderr, err)
	}
}
 

 

 

スポンサーリンク

 - Go言語