2016年7月1日金曜日

bashスクリプトの変数のスコープにはまったところと対処方法

The programming pitfalls in variable scope for Bash scripts

bashスクリプトを書いた際、変数が有効なスコープ範囲内にあるはずと思っていたのに値が消えてしまうトラブルにはまってしまいました。
その原因と対処方法をまとめました。


環境

  • Windows 10
  • Cygwin


きっかけは短縮URLの移動先を調べるスクリプト

Twitterのt.coを始め、Google URL Shortenerなど長い文字になりがちなURLを短縮するサービスが広く利用されています。
これらの短縮URLはWebブラウザーなどでクリックすると指定された移動先のURLに移動します。
短縮URLの文字を見ただけでは移動先のサイトは分かりません。
短縮URLの移動先がさらに短縮URLで別の移動先が指定されていることも少なくありません。

そこでCygwinで短縮URLの移動先を再帰的に調べ最後の移動先を表示するbashスクリプトを書いたのですが、変数の値が途中で消えてしまいました。

blog.fujiu.jp bashスクリプトで変数スコープにはまった


curlコマンドをインストールする

curlコマンドが必要です。Cygwin Setupかapt-cygなどでcurlをあらかじめインストールしてください。


失敗したスクリプト

動くはずと思って書いたスクリプトです。


上のスクリプトをファイルに保存しパーミッションを755に設定します。
引数に適当な短縮URLを指定して実行すると、curlコマンドを使って応答ヘッダーを調べます。
移動先が指定されていればそのURLの応答ヘッダーを調べる処理を繰返し、最後の移動先を表示するはずでした。

実際に実行してみると
(1)のstatus変数には間違いなくHTTPステータスが代入されている
(2)のstatus変数は値がカラになっている
という期待を裏切る結果が起きました。


原因

下記サイトを参考にしました。
スマートな紳士のためのシェルスクリプト(8):シェルスクリプト最大の罠、while問題 (1/2)- @IT
http://www.atmarkit.co.jp/ait/articles/1209/14/news147.html
http://www.atmarkit.co.jp/ait/articles/1209/14/news147.html

原因はパイプでつないだ先の変数はパイプ先のみ有効とのことです。
上のスクリプトの場合、パイプでつないだwhile文の内側にある(1)のstatus変数はdoneの直前まで有効ですが、doneより下にある(2)のstatus変数はパイプの外側にあるので別の値を持つ変数だった、ということでした。


解決策

パイプでつないだ先の変数の値を/tmpディレクトリーにファイルとして保存することにしました。


修正したスクリプト

期待通りに動作するように修正したスクリプトがこちらです。


/tmpディレクトリーをRAMディスクに置ければちょっとだけ高速化できそうです。


関連ブログ

[クラウド] BluemixのJavaアプリ開発ではまったところと対処方法
C#のAzure用Webジョブ開発ではまったところ

以上、参考になれば幸いです。

2016年6月25日土曜日

[Android] Xamarin で jar (Javaライブラリー) を実行する方法

How to run Jar libraries on Xamarin.Android

前回 Android Studioで作ったjarライブラリーファイル
をAndroid向けXamarinで実行します。


環境

  • Windows 10
  • Visual Studio Community 2015


既存のAndroid用ソリューションに Bindings Library を追加する

XamarinでJarライブラリーを実行するために Bindings Library プロジェクトを追加します。
Visual Studioを起動してAndroidアプリ用ソリューションを開きます。
ソリューションエクスプローラーのソリューションを右クリックして
追加 - 新しいプロジェクト
をクリックします。
blog.fujiu.jp [Android] Xamarin で jar (Javaライブラリー) を実行する方法

Bindings Library (Android) を追加します。
名前は BindingFujiuJar としました。

これでソリューションに BindingFujiuJar が追加されました。


Bindings Library プロジェクトにjarファイルを追加する

今回実行するjarファイルの中は StringDate というクラスに getNow() というメソッドがあります。 ソースはこちら

BindingFujiuJar の Jars フォルダーを右クリックして
追加 - 既存の項目
をクリックしてAndroid Studioで作ってjarファイルを追加します。


追加したjarファイルのプロパティのビルドアクションを EmbeddedJar に変更します。

今回のjarライブラリー化したクラスは Try-with-resources を使っているので、Xamarin.Androidプロジェクトのプロパティーの Compile using Android Versions を19以上に設定する必要がありました。
Android SDKの最新版をダウンロードし、「Use Latest Platoform」にしておきました。


既存のAndroid用プロジェクトの参照を設定する

Android用プロジェクト (先ほど追加したBindings Libraryではない方) の参照を右クリックして 参照の追加 をクリックします。

プロジェクト内にある先ほど追加した BindingFujiuJar をチェックしてOKをクリックします。

これで準備が整いました。


C#のクラスからJavaのjarライブラリーのクラスを実行する

オブジェクトブラウザーでJavaのパッケージ名はC#の名前空間に変換された結果を確認します。

jp.fujiu.fujiujp_jar
というJavaパッケージ名は
JP.Fujiu.Fujiujp_jar
という名前空間に変換されました。

C#のコーディングスタイルに合わせて1文字目とピリオドの次は大文字で書くとして、2文字目のPも大文字に変換されました。
またJavaの getNow() というメソッド(アクセサー)はC#の Now というプロパティに変換されます。

JavaのStringDateクラスのgetNow()メソッドを呼び出すActivityをXamarinのC#で書いてみました。
ボタンをクリックするたびに結果をToastに表示するActivityの例です。



実行結果

Docomo SH-06E (Android4.2、APIレベル17)で正常に実行できました。

Xamarin.Formsソリューションでは .Droidプロジェクトから実行することができました。


まとめ

  • jarファイルのビルドアクションはEmbeddedJarに設定する
  • Javaのパッケージ名はC#の名前空間に変換される。一部大文字に変換されるので注意
  • Javaのgetやsetで始まるメソッド(アクセサー)はC#のプロパティに置き換えられる
    例: getNow() → Now


注意点

C#からJavaのコードを実行するのにリフレクションを使っているようです。
リフレクションは非リフレクションと比較すると遅い実行方法なので速さが求められる処理には向きません。
C#への移植が困難で速さを犠牲にしてもいい場合以外は使用を控えた方が良さそうです。


トラブルシューティング

実行時に JNIEnv.FindClass ClassNotFoundException が発生する

プロジェクトのクリーンとビルドをし直したら発生しなくなりました。



関連ブログ

[Android Studio] Xamarin で実行可能な jar (Javaライブラリー) の作り方
[Android] Xamarin でアプリを作ってみました
Android Studioを使ってみました
[Unity3D] Unity5のプロジェクトをAndroid Studioにインポートする方法
[Java] Android StudioやEclipseのお節介な警告を消す方法
[Android] アナログ時計アプリをライブ壁紙に改造する

以上、参考になれば幸いです。

2016年6月18日土曜日

[Android Studio] Xamarin で実行可能な jar (Javaライブラリー) の作り方

How to create JAR libraries for Xamarin.Android

XamarinはC#でAndroidやiOSなどのアプリケーションを開発できるマルチプラットフォーム開発ツールです。
Android向けXamarinアプリは Bindings Library でjarファイルを実行することもできます。
jarファイルはJavaのコンパイル済みクラスをまとめたライブラリーファイルです。
ただしEclipseのみで作ったjarファイルは実行できませんでした。
Android向けXamarinで実行できるjarファイルをAndroid Studioで作る方法をまとめました。


環境

このブログを書いた時点の最新バージョンを使っています。
  • Windows 10
  • Android Studio 2.1
  • Java SE Development Kit 8u91


jarライブラリー化したいクラスを決める

今回はシンプルに現在日時を文字列で返すクラスをjarライブラリー化します。
ソースは次の通りです。

StringDate.java



Android Studio で クラスをjarファイル化する

プロジェクトにModuleを追加する

新規プロジェクトを作っても既存のプロジェクトを使ってもいいです。
Android StudioのProjectウィンドウを右クリックし、
New - Module
を追加します。
blog.fujiu.jp [Android] Xamarin で実行できる jar (Javaライブラリー) の作り方

Moduleの種類はAndroid Libraryを選びます。

Moduleの名前は fujiujp_libs としました。
今回jar化したいクラスは Try-with-resources を使っているので Minimum SDKは19以上に設定する必要がありました。
Minimum SDKはGradleのminSdkVersionを修正して変更することもできます。

ModuleにJavaクラスを追加する

Projectウィンドウのfujiujp_libsのツリーを開いてJavaクラスを追加します。

Gradleファイルにスクリプトを追記する

Projectウィンドウの Gradle Scripts のツリーを開いて build.gradle (Module: fujiujp_libs) を編集します。
このファイルに次のコードを追記します。




jarファイルをビルドする

Gradleウィンドウを開いて左上の Refresh All Gradle Projects をクリックします。

fujiujplibsというGradleが追加されるのでツリーを開いて
Task - other fujiuJpJar
をダブルクリックします。


これでプロジェクトフォルダーの fujiujp_jar\libs\ に FujiuJpLib.jar という名前でjarファイルができました。

次回はこのjarファイルのクラスをXamarinから実行します。



関連ブログ

[Android] Xamarin でアプリを作ってみました
Android Studioを使ってみました
[Unity3D] Unity5のプロジェクトをAndroid Studioにインポートする方法
[Java] Android StudioやEclipseのお節介な警告を消す方法
[Android] アナログ時計アプリをライブ壁紙に改造する
Live2Dを使ってみました

以上、参考になれば幸いです。

2016年6月11日土曜日

外付けハードディスクを完全消去して処分する方法

How to erase hard disk drives perfectly

ハードディスクに保存されたファイルは削除しても簡単に復元できることがあります。
物理フォーマットして消去しても高い技術力があれば消去する前の情報が復元できると言われています。

パソコンをはじめ最近のゲーム機やテレビ録画機にはハードディスクが内蔵されています。
これらのハードディスクには個人情報や人に知られたくない情報も少なからず記録されています。
ハードディスクを処分する際には可能な限り復元できないように消去したいものです。


環境

  • Windows 10


VirtualBoxにLinux OSをインストールする

CD-ROMドライブやUSBメモリードライブから起動して完全消去するソフトはいくつかありましたが、ほとんどが内蔵ドライブを消去するためのソフトでした。
Windowsで外付けドライブを消去するため、VirtualBoxにUbuntu Linuxをインストールして消去することにしました。
blog.fujiu.jp 外付けハードディスクを完全消去する


フォーマットしたいハードディスクをUSB接続できる装置に接続する

ハードディスクにはSATA、SAS、IDEなど複数の接続規格があります。
規格にあったUSB接続できるケースを買って設置します。
下の画像はIDE規格のハードディスクをUSB接続するケースです。
これでPCにUSB接続できます。


USBハードディスクをVirtualBoxに接続する

パソコンにハードディスクをUSBケーブルで接続します。
VirtualBoxを管理者として実行します。
接続したUSBハードディスクをVirtualBoxの
デバイス - USB
からチェックを入れます
これでLinux OSにUSBハードディスクが接続されました。


USBハードディスクのデバイスパスを調べる

消去したくない外付けハードディスクが接続されている場合は誤って消去しないように全て取り外します。
Gpartedを起動します。
インストールされてない場合は次のコマンドでインストールします。
sudo apt-get install gparted

Gpartedの画面右上のドロップダウンメニューから目的のUSBハードディスクを探します。
/dev/sda の下に /dev/sdb とか /dev/sdc があるはずです。
今回は /dev/sdb でした。


ddコマンドでハードディスクにランダムな内容を書き込みする

次のコマンドで /dev/sdb にランダムな内容を先頭から順に書き込みます。


最後まで書き込みが終わると次のメッセージが表示されます。


これを数回繰り返せば復元はほぼ不可能です。

最後まで書き込みが終わるには、容量に比例して時間がかかります。
強制終了する場合は、Ctrlキーを押しながらCキーを押します。

120GB、7200rpmのハードディスクを途中で強制終了した結果は次の通りでした。

1950380+0 レコード入力
1950380+0 レコード出力
7988756480 バイト (8.0 GB) コピーされました、 720.32 秒、 11.1 MB/秒

1GB当たり90秒、120GB全体で3時間かかる見込みでした。

ハードディスクは先頭にファイルの配置情報が記録されるので、最初の数GBをランダムに書き込むだけでも復元を困難にできます。

消去後は無料で合法の手段で処分する

消去して不要になったハードディスクはリサイクル業者に処分してもらいました。
不要になったパソコンを無料で廃棄する方法


なぜランダムな内容で復元を防げるのか

消去したハードディスクを復元する方法は、ハードディスクを分解し中のプラッターを電子顕微鏡で撮影し、ヘッドの通り道の脇に残った磁粉の並び方解析して消去する前の情報を復元するという手法です。
気の遠くなる作業ですが、技術の進歩次第で瞬時に解析される可能性があります。
ランダムな内容を繰返し上書きすれば脇に残った情報からの復元が困難になります。

USBメモリードライブやSSDは同じ手法で復元できません。



関連ブログ

不要になったパソコンを無料で廃棄する方法
(失敗談) ハードディスクを処分する
[Windows8] Paragon Hard Disk Manager

以上、参考になれば幸いです。

2016年6月4日土曜日

不要になったパソコンを無料で廃棄する方法

How to throw away PC for free

長いことほったらかしていた液晶モニターを廃棄することにしました。
資源有効利用促進法によりリサイクルマークがないパソコンや液晶モニターを地元で廃棄すると3240~4320円ほどかかるようです。


処分したもの

17インチ液晶モニター
blog.fujiu.jp 不要になったパソコンを無料で廃棄する方法

接触不要の多いキーボードやマウス

これらを一つの箱でまとめて発送しました。


引き取り業者を探す

インターネットで検索すると不要になったパソコンやゲーム機を着払いで引き取ってくれる業者がたくさん見つかります。
業者ごとに引き取り可能な条件が異なります。
引き取り拒否された場合は着払い分の送料が自分に請求されます。

特にパソコンを廃棄するときは次の点に注意が必要です。
  • 故障品でもよいか
  • ハードディスクやメモリーモジュールなどの欠品があってもよいか
  • ラックマウント型筐体でもよいか
  • 周辺装置も引き取ってくれるか
  • パソコン以外の電化製品を引き取ってくれるか

今回は上記条件を満たしている業者を選びました。
https://pc-farm.co.jp/


モニターの液晶が割れないように保護する

今回利用したサービスは液晶割れのモニターは無料で引き取らないとのことでした。
運送中に液晶が割れないように段ボールをビニール紐で縛り付けて保護しました。


段ボール箱に梱包する

一番苦労したのが手頃な段ボール箱を探すことでした。
ほとんどの業者は着払いで引き取れる箱一つ当たりの大きさと重さを次のように定めています。
  • 縦・横・奥行きの合計が160センチ以下
  • 重さが25kg以下
段ボール箱はスーパーマーケットやホームセンターで無料でもらえるのですが小さい箱ばかりで、モニターが入る大きさの段ボール箱は5軒くらい回ってようやく見つけました。

箱の中の隙間は新聞紙を丸めて詰めました。


着払いで発送する

指定された運送業者に着払いで発送を依頼します。
到着しても連絡はありません。


パソコンやゲーム機を廃棄する場合の注意

ネットで検索すると、パソコンやゲーム機のハードディスクを無料で消去するサービスを謳う業者もあります
ハードディスクを消去するにはそのハードディスクを読み取れる装置につなぐ必要があります。
もしその装置がマルウェアに感染していたら自分のデータが流出する可能性があります。
業者を疑うわけではありませんが、自分のハードディスクは自分で消去した方が安全です。
ハードディスクのデータを高い精度で消去するフリーウェアなどを使って消去してから廃棄することをお勧めします。



関連ブログ

[セキュリティ] ハードディスクを処分する (失敗談)
[Windows] 掃除しやすいキーボードにこだわる
Windows XPだったパソコンにFedoraやUbuntuをインストールできなかった失敗談
XPパソコンにCentOS Linuxを上書きインストール

以上、参考になれば幸いです。

2016年5月28日土曜日

[Machine Learning] 機械学習で白黒写真をカラー化する方法

How to color monotone photo with the machine learning

ディープラーニング アプリケーション「Automatic Colorization of Grayscale Images」
https://github.com/satoshiiizuka/siggraph2016_colorization
を使って白黒写真をカラー写真にしてみました。
その手順をまとめました。


環境

  • Windows 10のVirtualBoxにUbuntu Linux 15.10をインストールした


Linux OSを用意する

Cygwinへのインストールを試みましたがTorch7が「platform not supported, aborting」というエラーでインストールできませんでした。
このアプリは
  • Ubuntu Linux で開発された
  • GPUを使わない
とのことなので、VirtualBoxにUbuntu Linuxをインストールして使うことにしました。

ちなみにCentOSは7のみ、Fedoraは20と22のみをサポートのようです。
blog.fujiu.jp 機械学習で画風を変換する方法


インストール

必要なソフトを全てインストールします。

gitをインストールする



Torch7をインストールする



最後に
Do you want to automatically prepend the Torch install location to PATH and LD_LIBRARY_PATH
と表示されるので yes と入力します。
これで .bashrc にexportコマンドが追記されるので次のコマンドで環境変数を更新します。


インストール後のソースは不要のようです。ソースを消すコマンドは次の通り。


必要なパッケージ群をインストールする



siggraph2016_colorization をダウンロードする



これで必要なソフトが揃ったはずです。


白黒画像をカラー化する方法

カラー化したい白黒の画像はpngフォーマットだと「Wrong number of input channels!」というエラーに悩まされるのでjpgフォーマットをお勧めします。
Ubuntuならconvertコマンドでjpgに変換できます。

また、画像サイズが横512×縦512ピクセルを超えると処理が遅いとのことです。
縦横とも512ピクセル以内なら1秒以内に終わります。

白黒画像をホームディレクトリに
monotoon.jpg
というファイル名で置いた場合、次のようなコマンドを実行すると result.png というファイル名でカラー化されます。



こんな画像を処理したら

こうなりました。

白黒にする前の画像がこちらです。

別の画像ではこうなりました。
上から原画・白黒化画像・カラー化画像の順です。

いろいろ試してみましたがセピア調になることが多いです。

風景写真のカラー化は安定してますが人工物の写真やアニメ調のイラストは苦手のようです。


関連ブログ

[GPGPU] 機械学習で画風を変換する方法
Android4.0をVmwareやVirtualBoxで起動する
Windows8をVirtualBoxにインストールする

以上、参考になれば幸いです。

2016年5月21日土曜日

[GPGPU] 機械学習で画風を変換する方法 [Machine Learning]

How to install and use the chainer-gogh

2015年9月に公開された画風を変換するアルゴリズム「chainer-gogh」をインストールして使ってみました。
https://github.com/mattya/chainer-gogh
使い方までの手順をまとめてみました。


環境

  • CUDAコア数が48、動作周波数が900HMzのNVIDIAグラフィックスを搭載したノートPC
  • 64bit版 Ubuntu Linux 15.10


CUDA Toolkitが使えるLinux PCを用意する

CUDAはNVIDIA製の一部のグラフィックスに搭載される並列演算に特化した機能です。
CUDA ToolkitはCUDAの機能を利用するための開発環境です。
chainer-goghはCUDA Toolkitを利用すると高速に処理できます。
今回はchainer-goghをCygwinやホストOSがWindowsのVirtualBoxで実行したのですが、このブログを書いている時点ではどちらもCUDA Toolkitが利用できず、画像1枚変換するのに90時間ほどかかりそうでした。

そこでUSBメモリードライブにUbuntu 15.10をインストールして使いました。
blog.fujiu.jp 機械学習で画風を変換する方法


必要な環境をインストールする

Ubuntu 15.10でchainer-goghを使えるようにするまでインストールするものが沢山ありました。
すべて端末からインストールしました。

グラフィックスドライバーをインストールする

システム設定 - ソフトウェアとアップデート - 追加のドライバー
から検証済みのドライバーをインストールしました。

NVIDIA純正のドライバーは
  • インストール時にX Serverを停止する必要がある
  • インストール後にOSが起動しない
などの問題がありました。

また、Ubuntu 16.04では検証済みのドライバーのインストール後にX-Windowでログインできなくなるトラブルがありました。

CUDA Toolkit をインストールする



インストール後は次の環境変数の設定が必要です。~/.bachrc に追記しておくと端末起動時に自動で設定されます。


cuDNNに対応していればインストールする

cuDNNはCUDAの処理を最適化をする機械学習用ライブラリーです。
Accelerated Computing Developer Programにユーザー登録するとダウンロードできます。
cuDNNが使えればchainer-goghの高速化が期待できますが、今回はPCが対応してなかったので使えませんでした。

GCC4.9ををインストールする

Ubuntu 15.10はGCC5がインストールされていますが、ChainerフレームワークのインストールにはGCC4.9が必要でした。


Pythonのライブラリー群をインストールする

下記のコマンドだと不要なものもあるかもしれませんが、必要なものが欠けてると何もできないのでまとめてインストールします。


Chainerフレームワークをインストールする



次のコマンドを実行して何も表示されなければCUDAが使えます。


このコマンドを実行して
ImportError: No module named cupy
と表示されるようならCUDA Toolkitがインストールされてないか環境変数が正しく設定されてません。
CUDA ToolkitがインストールしてChainerフレームワークをインストールをインストールし直してください。

gitをインストールする



chainer-goghと学習モデルをインストールする

学習モデルは作者曰く「お手軽」のものを使いました。


これで必要な環境が揃ったはずです。


使い方

ホームディレクトリに
変換したい画像 input.png
画風スタイルの画像 style.png
がある場合、次のコマンドで変換できます。


処理中はホームディレクトリに img_・・・・.png という画像ファイルが作られます。
im_04950.png が完成です。下が完成の画像です。

所要時間は次の通りでした。
  • CPUのみで推定90時間
  • CUDAで約45分
  • cuDNNは未対応なので検証不可

白地が多い画像は苦手のようです。


トラブルシューティング

実行したらCUDAに対応していなかった (cannot import name core)

CUDAを使わずに実行する


cuDNNをインストールしたらcuDNNに未対応で実行できない (CUDNN_STATUS_ARCH_MISMATCH)

環境変数のcuDNNのパス設定を削除してChainerフレームワークを再インストールする。

Chainerフレームワークを再インストールする方法



GCCを元に戻す方法




関連ブログ

Android4.0をVmwareやVirtualBoxで起動する
Windows8をVirtualBoxにインストールする
[Blender] Pythonで複数の設定を一瞬で編集する方法

以上、参考になれば幸いです。