ページ

2021年2月27日土曜日

Bash でプロセスの死活チェックをスマートにやる方法

プロセス名を hogehoge としたとき,

よく見かけるのはこんな感じ.
#!/bin/bash

ProcessName=hogehoge

IsActive=`ps aux | grep ${ProcessName} | grep -v grep | wc -l`

if [ ${IsActive} -gt 0 ]; then
  echo "${ProcessName} is Active."
else
  echo "${ProcessName} is Disactive."
fi

exit 0


ps aux で全てのプロセスを表示して,それをプロセス名でgrep し,ただし grep 自身もヒットしてしまうので,それを grep -v で除き,最後に wc でライン数を数える.そのライン数が0よりも大きければプロセスが存在する.と判定する.

やっていることはよく判ります.でもパイプで色々繋いだりすると,想定外の例外で引っかかることが多い...

(例えばプロセス名自体が,どこかに「grep」を含んでいる場合,この方法では検出できない)

これをもうちょっとスマートにやる方法を紹介します

2021年2月22日月曜日

Linux でGUI を自動操作するツール【自作】

GUI の自動ツールとしては,xdotool などが有名だが,そういったツールを使用できない場合は自作するのもひとつの手段.

マウスポインターを指定した座標に動かして,クリックするだけのプログラムならば,数行のコードで実現できる.

click.c
--------------------------------------------------------------------------------
#include <stdlib.h>
#include <X11/extensions/XTest.h>

int main ( int argc, char ** argv )
{
  // Arguments 1 is Point of X, Argument 2 is Point of Y
  int position[2] = {atoi ( argv[1] ), atoi ( argv[2] ) };

  // Open Default Display
  Display * display = XOpenDisplay ( NULL );

  if ( display != NULL )
  {
    // Open 'Virtual core XTEST pointer'
    XDevice * device = XOpenDevice ( display, 4 );

    if ( device != NULL )
    {
      // Move Poitner
      XTestFakeDeviceMotionEvent ( display, device, False, 0, position, 2, 0 );

      // Press & Release Left Button
      XTestFakeDeviceButtonEvent ( display, device, Button1, True, NULL, 0, 0 );
      XTestFakeDeviceButtonEvent ( display, device, Button1, False, NULL, 0, 0 );

      XCloseDevice ( display, device );
    }

    XCloseDisplay ( display );
  }

  return 0;
}


 $ gcc -lX11 -lXi -lXtst click.c -o click
 $ ./click 100 500

2021年2月15日月曜日

Subversionの接続先のURLを変更する

サーバーの老朽化や,VPSの引っ越し,その他設定の見直し等々,Subversion のホストが変更になることは珍しいことではない.

接続先が変更された場合,ローカルのチェックアウトを無かったことにしてしまうのも一つの手だが,コミットする前の変更ファイルを引き継ぎたい場合などは,接続先を変更すると良い.

といっても,とても簡単で,svn switch --relocate [変更前の接続先] [変更後の接続先] とするだけ.

2021年2月10日水曜日

【MySQL】 ソートで NULL を一番最後にするとき,IS NULL ASC としてはいけない理由.

少々挑戦的なタイトルですが,本当は IS NULL ASC で全然構いません.(笑)

ただ私が言いたいのは,魔法の呪文のように意味も分からず IS NULL ASC とするのはやめたほうが良い.
より厳密には,それだけ覚えてしまうのは勿体無い.ということです.

IS NULL ASC のように ORDER BY 句を用いれば,様々な条件でソートすることができるので,この記事では,
なぜ IS NULL ASC で NULL を後ろにできるのか実演しながら,より汎用的な条件付きソートについて考えていきます.

サンプルとして以下のようなテーブルを用意しました.(例によってラズパイを使っているので MariaDBですが,基本的に MySQL でも同じです)
 MariaDB [sample]> SELECT * FROM SAMPLE;
 +------+-------+
 | id   | value |
 +------+-------+
 |    1 |     0 |
 |    2 |    10 |
 |    3 |     4 |
 |    4 |  NULL |
 |    5 |     8 |
 |    6 |     1 |
 |    7 |     3 |
 |    8 |     2 |
 |    9 |  NULL |
 |   10 |    -5 |
 +------+-------+

2021年2月7日日曜日

【MySQL,MariaDB】 レプリケーションを設定する

データベースでマスタースレーブ型のレプリケーションを設定する方法を示す.
手元のラズパイ2台を使用するため,MariaDBで設定するが,基本的にはMySQLも同様の方法でできるはずだ.

データベースの初期設定手順は以下のエントリーを参照されたし.
WM×LI: Raspberry Pi にデータベースを構築する【MySQL,MariaDB】

Raspberry Pi のモデル名を確認する

性能が段違いなので,基本的なことはラズパイ4 にやらせているが,敢えてラズパイ4 からは切り離して可動させているサービスもあったりするので,我が家ではラズパイ3,ラズパイ2 もまだまだ現役だ.

基本,ホスト名で判別しているが,どのラズパイがどのモデルだったか分からなくなることが時々ある.

そんなときは,/proc/device-tree/mode を確認すると,モデル名が表示される.

2021年2月6日土曜日

Raspberry Pi で初回起動時からsshでアクセスする方法

何番煎じかわからないけれど,Raspberry Pi用のmicro SDカードにRaspberry Pi OSをインストールした直後の初回起動時からsshでアクセスできるようにする方法.

結論から言うと,/boot/ 直下に ssh という名前のファイルを置くだけ.

それでは細かい手順を解説します.

2021年2月4日木曜日

マルチスレッドなプログラムをgdbでデバッグする

たまにはエンジニアらしくソフトウェアのお話を.

マルチスレッドなプログラムを書くとき, 常に念頭に置きながら設計しなければならないのが排他制御だが,そんなとき,どの処理がどのスレッドで実施されているか表示できることは非常に有効なテクニックだ.

そこで次のようなコードで実験する.

<サンプルコード:test.cpp>
test.cpp
--------------------------------------------------------------------------------
#include <iostream>
#include <thread>
#include <unistd.h>

void a( void )
{
  for( int i = 0; i < 30; i++ )
  {
    std::cout << "i : " << i << std::endl;
    sleep( 1 );
  }
}

void b( void )
{
  for( int j = 0; j < 10; j++ )
  {
    std::cout << "j : " << j << std::endl;
    sleep( 3 );
  }
}

int main( void )
{
  std::thread * _a = new std::thread( a );
  std::thread * _b = new std::thread( b );
  _a->join();
  _b->join();
  return 0;
}

※本来は,coutする前後でmutexを貼る必要があるが,今回は可読性重視で割愛する.

これをコンパイルして,gdbで実行する
 $ g++ -g -pthread test.cpp -o test
 $ gdb ./test