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

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

Vala言語で外部プロセスを実行する(簡単な例・コード例と出力結果)

Vala言語で外部プロセスを実行する(簡単な例・メモ)」の続き。
ここではGLib.Process.spawn_command_line_async()GLib.Process.spawn_command_line_sync()のそれぞれを用いたテストコードとその実行結果を貼り付ける。

  1. GLib.Process.spawn_command_line_async()を使用した例
  2. GLib.Process.spawn_command_line_sync()を使用した例

GLib.Process.spawn_command_line_async()を使用した例

[任意]ファイル名: spawncmdlineasynctest.vala

using GLib;

/*
 * valac -o spawncmdlineasynctest spawncmdlineasynctest.vala
 * valac -D FAIL -o spawncmdlineasynctest_fail spawncmdlineasynctest.vala
 * valac -D WAIT -o spawncmdlineasynctest_wait spawncmdlineasynctest.vala
 */

namespace SpawnCmdlineAsyncTest
{
  class MainClass
  {
    public static int main (string[] args)
    {
#if FAIL
      string cmdline = "ls -5";     // 失敗する例
#elif WAIT
      string cmdline = "sleep 2";   // 時間のかかる例
#else
      string cmdline = "cal 7 2009";
#endif
      try
      {
        /*
         * async版は起動したらその後の情報は取得できない
         * メッセージ出力などはそのまま端末へ
         * 成功したかどうかは戻り値で真偽値として得ることもできる
         */
        GLib.Process.spawn_command_line_async (cmdline);
      }
      catch (GLib.SpawnError e)  // 子プロセス起動に失敗
      {
        print ("spawn failed: %s\n", e.message);
        return 1;
      }
      return 0;
    }
  }
}

下は実行結果。最後のsleepコマンドの例では子プロセスの終了と無関係にプログラムが終了しているのが分かる。

(正常に終了する例)
$ ./spawncmdlineasynctest
      7月 2009      
日 月 火 水 木 金 土
          1  2  3  4
 5  6  7  8  9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31


(エラーになる例)
$ ./spawncmdlineasynctest_fail 
ls: invalid option -- '5'
詳しくは `ls --help' を実行して下さい.

(停止する例)
$ ./spawncmdlineasynctest_wait
(すぐに終了する)

GLib.Process.spawn_command_line_sync()を使用した例

[任意]ファイル名: spawncmdlinesynctest.vala

using GLib;

/*
 * valac -o spawncmdlinesynctest spawncmdlinesynctest.vala
 * valac -D FAIL -o spawncmdlinesynctest_fail spawncmdlinesynctest.vala
 * valac -D WAIT -o spawncmdlinesynctest_wait spawncmdlinesynctest.vala
 */

namespace SpawnCmdlineSyncTest
{
  class MainClass
  {
    public static int main (string[] args)
    {
#if FAIL
      string cmdline = "ls -5";     // 失敗する例
#elif WAIT
      string cmdline = "sleep 2";   // 時間のかかる例
#else
      string cmdline = "cal 7 2009";
#endif
      string out_stdout, out_stderr;
      int status;
      /* LC_CTYPEをsetlocale()で指定しないと日本語が「?」になる */
      weak string? lc_ctype = GLib.Environment.get_variable ("LC_CTYPE");
      if (lc_ctype != null)
        GLib.Intl.setlocale (GLib.LocaleCategory.CTYPE, lc_ctype);
      try
      {
        /*
         * 中で標準出力/標準エラー出力の文字列とステータス値がセットされる
         * 成功したかどうかは戻り値で真偽値として得ることもできる
         */
        GLib.Process.spawn_command_line_sync (cmdline, out out_stdout, out out_stderr, out status);
        print ("-- stdout begin --\n%s-- stdout end --\n\n", out_stdout);
        print ("-- stderr begin --\n%s-- stderr end --\n\n", out_stderr);
        print ("raw status: %d", status);
        if (GLib.Process.if_exited (status))
          print (" exit status: %d", GLib.Process.exit_status (status));
        print ("\n");
      }
      catch (GLib.SpawnError e)  // 子プロセス起動に失敗
      {
        print ("spawn failed: %s\n", e.message);
        return 1;
      }
      return 0;
    }
  }
}

(2009/7/22)GLib.Process.if_exited()(C言語のWIFEXITEDマクロ)を使用してステータス値をチェックしてからGLib.Process.exit_status()を呼ぶように修正
下は実行結果。エラーになる例ではGLib.Process.exit_status()によりステータス値から戻り値(終了ステータス)が得られているのが分かる。

(正常に終了する例)
$ ./spawncmdlinesynctest
-- stdout begin --
      7月 2009      
日 月 火 水 木 金 土
          1  2  3  4
 5  6  7  8  9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

-- stdout end --

-- stderr begin --
-- stderr end --

raw status: 0 exit status: 0

(エラーになる例)
$ ./spawncmdlinesynctest_fail 
-- stdout begin --
-- stdout end --

-- stderr begin --
ls: invalid option -- '5'
詳しくは `ls --help' を実行して下さい.
-- stderr end --

raw status: 512 exit status: 2

(停止する例)
$ ./spawncmdlinesynctest_wait
(2秒間停止する)
-- stdout begin --
-- stdout end --

-- stderr begin --
-- stderr end --

raw status: 0 exit status: 0

なお、コード中のLC_CTYPEの指定を行う部分を削除すると下のように日本語が化ける。

$ ./spawncmdlinesynctest     
-- stdout begin --
      7? 2009      
? ? ? ? ? ? ?
          1  2  3  4
 5  6  7  8  9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

-- stdout end --

-- stderr begin --
-- stderr end --

raw status: 0 exit status: 0

使用したバージョン:

  • Vala 0.7.4