試験運用中なLinux備忘録・旧記事

はてなダイアリーで公開していた2007年5月-2015年3月の記事を保存しています。

GUIファイルマネージャから端末の中でPythonスクリプトを実行し、Enterキー入力で閉じるようにする

一般的に、実行属性の付いたテキストファイルを実行したときに(それを引数として)実行されるプログラムはそのテキストファイルの1行目に

#! [実行ファイルの絶対パス]

という記法で指定することができ(先頭の「#!」はshebang,行全体はshebang行と呼ばれる)、シェルスクリプトでは

#! /bin/sh

のように、bash固有の機能を用いている場合には

#! /bin/bash

と書かれるが、GUIファイルマネージャから1行目が「#! /usr/bin/python」や「#! /usr/bin/env python」のPythonスクリプトを実行する場合、PyGTKなどを用いたGUIアプリケーションであれば普通に実行・動作できるものの、端末で動かすちょっとしたテスト用のスクリプトを実行したいときなどには、スクリプトを実行しても出力がどこにも表示されなかったり、Nautilusのように端末の中で実行する指定ができるような場合でも、その端末ごと一瞬で終了してしまったりして出力が確認できない。また、先頭の行を省いたものを実行しようとしてもシェルスクリプトとして実行しようとして動作がおかしくなる。
(2010/10/5)通常時の実行のされ方についての記述を修正

  1. 実行方法を工夫する
  2. 実際
    1. スクリプト
    2. 使い方1: GUIファイルマネージャに関連付ける
    3. 使い方2: 実行属性付きのPythonスクリプトをダブルクリックで開きたい場合

実行方法を工夫する

しかし、以下のような実行の仕方をすることで、端末の中で対象のスクリプトを起動しつつその終了時に端末が終了せずにキー(Enter)の入力を待つようにできる。

GNOME端末を例として用いると

$ gnome-terminal --hide-menubar -t "[タイトル]" -x sh -c 'python "[スクリプトの場所]"; read'

のような実行の仕方となり、この要領に基づいたシェルスクリプトを用意してそれをPythonの実行ファイルの代わりに関連付けることでGUIファイルマネージャから端末の中でスクリプトを実行しつつ出力が確認できるようになる。

実際

以下にスクリプトと使い方を記述する。

終了時には戻り値を含むメッセージを表示するようにしている。

スクリプト
用意するのは下のようなシェルスクリプトとなる。必要と好みに応じて

  • Pythonの実行ファイル名(用いたいバージョンのものに設定・ディストリやそのバージョンによって異なる場合がある)*1
  • 用いたい端末エミュレータ(1つだけ行頭の「#」を消した状態にする・オプションも好みで編集可)

を編集してから用いる。
[任意]ファイル名: pyinterm.sh ライセンス: MIT

#! /bin/sh

# 引数に指定したPythonスクリプトをGUIファイルマネージャから実行して
# 端末を起動した中に結果を表示して待つためのスクリプト
#
# シェルでスクリプトとreadコマンドを続けて実行するようにすることで
# Enterキーを押したときに端末が終了するようになっている
#
# 別途GUIファイルマネージャからPythonスクリプトの種類に対して
# 「別のアプリケーションで開く」のような名前のコンテキストメニュー項目から
# このスクリプトの場所を指定した関連付けの設定を行うと
# コンテキストメニューのアプリケーション選択から実行できるようになる
# ダブルクリックでの実行がしたい場合は関連付けの代わりに各Pythonスクリプトの先頭の行を
# 「#! [このスクリプトの絶対パス]」にして実行するようにする必要がある
#
# version 20101004
# (C) 2010 kakurasan
# Licensed under MIT

## 用いたいPythonのコマンド名(用いたい実行ファイル名に合わせる・ディストリによって変わる)
PYTHON=python3
#PYTHON=python

## 使用したい端末エミュレータの行頭の「#」を削る
## (複数削ってしまうと複数の端末で続けて実行される)
## オプション指定は好みで変更可

## GNOME端末(GNOME)
gnome-terminal --hide-menubar -t "${1}" -x sh -c "${PYTHON} \"${1}\"; echo -e \"--- exited (status: \${?}) ---\"; read"

## Konsole(KDE)
#konsole -title "${1}" -e sh -c "${PYTHON} \"${1}\"; echo -e \"--- exited (status: \${?}) ---\"; read"

## Terminal(Xfce)
#terminal --hide-menubar -T "${1}" -x sh -c "${PYTHON} \"${1}\"; echo -e \"--- exited (status: \${?}) ---\"; read"

## LXTerminal(LXDE)
#lxterminal -e "sh -c \"${PYTHON} \\\"${1}\\\"; echo -e \\\"--- exited (status: \${?}) ---\\\"; read\""

## xterm
#xterm -title "${1}" -e sh -c "${PYTHON} \"${1}\"; echo -e \"--- exited (status: \${?}) ---\"; read"

## mlterm/直接起動
#mlterm -T "${1}" -e sh -c "${PYTHON} \"${1}\"; echo -e \"--- exited (status: \${?}) ---\"; read"

## mlterm/デーモンへの接続(別途デーモンの起動が必要)
#mlclient -T "${1}" -e sh -c "${PYTHON} \"${1}\"; echo -e \"--- exited (status: \${?}) ---\"; read"

## rxvt-unicode/直接起動
#urxvt -title "${1}" -e sh -c "${PYTHON} \"${1}\"; echo -e \"--- exited (status: \${?}) ---\"; read"

## rxvt-unicode/デーモンへの接続(別途デーモンの起動が必要)
#urxvtc -title "${1}" -e sh -c "${PYTHON} \"${1}\"; echo -e \"--- exited (status: \${?}) ---\"; read"

これを保存したらアイコンのコンテキストメニューから「プロパティ」の「アクセス権」や「パーミッション」のタブで実行可能にするためのチェックが入った状態にしておく(実行属性を付ける)。

使い方1: GUIファイルマネージャに関連付ける
Pythonスクリプトのあるディレクトリに移動し、コンテキストメニューの「アプリケーションで開く」「別のアプリで開く」といった名前の項目を選択し、一覧から外れた一番下の項目(「別のアプリ」「他のアプリケーションで開く」といった名前)を選択する。
次に、アプリケーション選択ダイアログが出るので、コマンド名を手動で入力する場所(Nautilusでは「コマンドを直接指定する」を展開したところ)で上のスクリプトの場所を絶対パスで入力するか参照ボタンから指定する。
これでPythonスクリプトコンテキストメニューの「アプリケーションで開く」「別のアプリで開く」といった名前の項目を選択したときの一覧からスクリプトの名前のものを選択すると端末の中でスクリプトが実行される。
しかし、この方法ではPythonスクリプトに実行属性が付いている場合はコンテキストメニューの階層をたどる必要があり、ダブルクリックで簡単に開くというわけにはいかない。今後同じプログラムが用いられるようにするチェックが入っていてもダメ。
(2010/10/5)Pythonスクリプトの実行属性を外すことで、GUIファイルマネージャの関連付け設定を用いてダブルクリックで上のスクリプトから開くようにすることはできる。

使い方2: 実行属性付きのPythonスクリプトをダブルクリックで開きたい場合
Pythonスクリプトを実行属性付きのままでダブルクリックで実行できるようにしたいのであれば、スクリプトの1行目を

#! [上のスクリプトの場所(絶対パス)]

にして実行すればダブルクリックで開くことができる。この場合、上の関連付けの設定は不要。しかし、端末のシェル上でそのスクリプトを実行したときにも新しく端末エミュレータが起動されてその中でPythonが実行されることになる(実行中の端末の中には表示されない)。

*1:Pythonのバージョンを選択できるようにしたかったので、直接スクリプトを実行するようにはしていない