備忘録」カテゴリーアーカイブ

tmux(byobu)でDISPLAY環境変数をリセット(re-set)する方法

私の調べ方が甘いのか日本語でこの手のことに関する記事が見当たらないのでメモ.
ssh先のマシンでtmuxのセッションを立ち上げたあとに,デタッチしてsshを切ったとする.このあともう一度つなぐとDISPLAY環境変数が変化してしまい,アタッチしたあとにX forwardingが動かないことがある.

これに対する解決策がこのページに書いてあった.
https://goosebearingbashshell.github.io/2017/12/07/reset-display-variable-in-tmux.html

このページに従うと,そもそも新しいtmuxでは,今の環境変数の状態を確認することができるらしい.

この中のDISPLAYが今の最も新しい(今のsshのセッション)の設定内容であるらしいのだ.ということはこの環境変数を再設定すれば使えるようになる.具体的には

とすれば良い.問題は,これを起動時に自動でやりたいということである.ただし,tmuxでアタッチ時に自動でコマンドを実行する方法がわからないので,とりあえずは.zshrcに上記の設定を書いて,必要であればシェル上で

を行うことで再設定するようにすることにした.もっといい方法もある気がするが,そんな頻繁に変化するものでもないので,とりあえずはこれでオッケ.

内容についてどう思いますか?
  • いいね (2)
  • だめ (0)

似ているgraphを探す方法

ある与えられたグラフに対して,全く同じ形をしているグラフを探す問題をグラフ同型判定問題という.数学の分野で同型という言葉が出てくるときは,一見同じようには見えない場合でも,見方(例えば記号の付け方)などを変えることで同じにできるような場合にそう呼ぶことが多い.この場合の同型も同じような意味合いである.グラフには大きく分けて有向グラフなのか無効グラフなのかという違いがあるが,ここでは話を簡単にするため無向グラフに限定する.実は,多くの実問題で計算量や問題設定の緩和を図るために有向グラフを無向グラフにすることは比較的ありふれた話である.したがって,以下の話は必ずしも有向グラフでは無駄というわけではない.

グラフの同型判定問題や,もしくはより難しい問題である,あるグラフの中に探したいグラフを一部として含むかどうかを探す部分グラフ同型判定問題はNPであることはわかっているものの,NP困難であるかどうかはわかっていない(Web上の記事によってNP完全だったりNP困難であったり,もしくはどちらかわかっていないと書かれていたり,実際のところどうなのかわからない).どちらにせよ,この問題を解くことが今の所容易ではないことは変わらない.多くの文脈(例えば化学式の検索など)で,このグラフ同型性判定問題を解決したいと考えられており,多くのアルゴリズムが今までに提案されてきた.

さて,私が今回,扱いたいのはこのグラフ同型性判定問題ではなく,より曖昧とした問題,すなわち2つのグラフの類似度を知りたいという問題である.

不完全マッチング(inexact matching)

今回扱いたいのは不完全マッチング(inexact matching)である.実はこの単語,論文中に出てきた表現であり,私の知る限り日本語訳を見たことがない.inexact matchingは直訳すれば不正確マッチングだが,不正確は日本語の意味合いを考えると,誤解を招きかねない.完全マッチングという別の用語はあるものの,不完全という用語がおそらく今回の意味ではピッタリのように感じられるので,ここでは便宜上,不完全マッチングと呼ぶことにする.

さて,不完全マッチングとは要するに,与えられた2つのグラフは同型ではないのだが,微妙に似ており,その上で2つのグラフ間の最も妥当なノードもしくはエッジの対応付けはどのようなものかという問題である.この対応付けがわかると,2つのグラフの間の距離のような概念まで導入することができ,一昔に流行ったSVNではカーネル法に帰着できると分類問題に帰着可能になるため,このグラフ間の距離を求めることにはビッグデータなどの応用も含めて,一定の需要があるらしいのだ.さて,不完全マッチングでは,この妥当な対応付けというところが味噌で,不完全マッチングを提供するアルゴリズムによって,妥当の意味が違ってくる.一番多く使われているのは,グラフ編集距離(graph edit distance)と呼ばれるものを用いるやり方である.これは文字列に対する編集距離に概念としては近い.グラフのノードもしくはエッジの追加や削除などを行って,片方のグラフをもう片方のグラフに近づけたときに,最も少ない手数で対応付けられたときのコストをもって,2つのグラフの距離とする.また,このときに対応付けられたノードもしくはエッジが今回の場合の答えになるというものだ.しかし,この最も最短のグラフ編集の手順を探す問題はNP困難であることが知られている.最も高速に厳密解を得る方法としては,A*アルゴリズムを用いる方法があるが,この方法ではたかだか15ノード程度が求められる関の山で,それ以上となると手も足も出ない.そこで,これまでに提案されたアルゴリズムでは,近似的にこの問題を解く方法が模索されてきた.

もう一つのこの問題の考え方は,2つのグラフのノード,エッジ同士の対応付に関する適応関数を定義し,その適応関数が最大となるような割当を探す問題に帰着させる方法である.この方法では,予め2つのグラフ間のノードもしくはエッジを対応付けした際の利益のようなものを設定しておく.例えば,グラフA, Bについて,Aの1番めのノードとBの2番めのノードを対応付けたら,10点だとか,Aの2番めとBの2番め同士なら5点みたいな感じである.その上で,すべてのノードとエッジを対応付けたあとのすべての適応値の合計が最大となるように対応付けを行ったときの対応をマッチングの結果とするのである.

上記の2つのやり方,すなわち
1. グラフの編集距離を最小とするやり方
2. グラフの各要素の対応付で最も適応関数の値が最大となるものを探すやり方
の2つは,本質的に違う問題のように感じられるだろうが,実はどちらについても二次割当問題(QAP)というNP困難な問題に帰着できることが知られている.したがって,結局の所,この問題を解くことはQAPを如何に高速に解くかという話になる.

手っ取り早く最新の結果を使いたい人へ

本当は,このあとにこの問題がどうして二次割当問題に帰着可能で,過去の研究ではいかにしてこれを解こうとしているのかを説明しようと思ったのだが,今回も例に漏れず面倒になってきたので,すでにあるライブラリだけ紹介して終わりにする.余裕があれば,そのあたりの話も追記したい.調べた感じでは,次の3つのgithubの実装が役立ちそうだ.
– https://github.com/bgauzere/graph-lib
– http://www.f-zhou.com/gm_code.html
– https://github.com/egbertbouman/fgm-cpp
上記の内,2つはC++で実装されており,残りの一つはMatlabだ.特にこれらは割と最近の結果(2017年)のものまで含まれており,その論文によれば500ノードくらいまではぼちぼち動くらしいので,それなりに使い物になるのではないかと思う.

内容についてどう思いますか?
  • いいね (2)
  • だめ (0)

NISの環境からLDAPへの移行

今まで研究室のアカウント管理はNISで行っていましたが,やはり様々なサービスを一元管理できるLDAPの方が良いのではないかということで,LDAPに移行することにしました.研究室内のドキュメントはCrowiで管理しているためマークダウンで記述可能であり,ブログにそのまま投稿できます.そこでこちらのブログにも備忘録として残しておこうと思います.

LDAPの仕組み

NISとくらべてLDAPは様々なことが出来ますが,その代わり比較的複雑です.そこで簡単にですがLDAPを俯瞰することから始めてみようと思います.

基本的な考え方

LDAP (Lightweight Directory Access Protocol)とはディレクトリのように階層構造をなした,データベースのようなものです.一般的なデータベースと言えばSQLなどを指しますが,階層構造があるという点が大きく異なります.わかりやすく説明するのが難しいのですが,素晴らしい参考資料がネットの海に漂っていましたので,ここに挙げておきます.
LDAPの基礎知識
20070423odagiri2.pdf

一応簡単に説明すると,エントリーと呼ばれるノードが階層構造をなして木構造的になったようなものがLDAPで扱うデータです.

上の図では,comが一番根本のエントリーで,そこからpeopleまで枝が伸びています.これをlinux的なディレクトリ構造では/com/test/www/peopleと表現することになるわけですが,LDAPではou=people,dc=www,dc=test,dc=comという長ったらしい表現で表します.ここでouとかdcは属性と言って,それが一体どんなエントリーであるか(linuxで言えばどんなデータが入ったディレクトリなのか)を説明し,イコールで結ばれた右辺はその値(属性値)を表します.属性には主に次のような種類があります.

属性名 属性表記 意味
cn common name 人やモノの名前など
dc domain component ドメイン名
ou organization unit name 組織単位
o organization 組織名

したがって,ou=people,dc=www,dc=test,dc=comは,dc=www,dc=test,dc=comというドメイン配下のpeopleという組織単位のエントリーであるということを意味します.例えばpeopleにTanakaという人を追加したいときには,uid=Tanaka,ou=people,dc=www,dc=test,dc=comというエントリーを作成すれば良いわけです.また,エントリーは木構造をなしているので,枝分かれをしてもかまいません.例えば,dc=www,dc=test,dc=comだけでなく,dc=mail,dc=test,dc=comというドメインを同時に作ることが出来ます.この場合は,どちらもdc=test,dc=comの下に作成されることになります.

ドメインはあたかもネットワークのFQDNのような形をしていますが(例えばこの場合,www.test.com),必ずしも現実のFQDNに従う必要はありません(おそらく).単にそういう習慣付けが行われているだけだと思います.

ある団体があって,それがdc=www,dc=test,dc=com以下にエントリーとしてデータを持っている場合を考えましょう.このとき,例えば組織内のグループを表現するエントリーou=Group,dc=www,dc=test,dc=comの配下にあるkame_sann_teamにアクセスするためには,cn=kame_sann_team,ou=Group,dc=www,dc=test,dc=comと書かなければなりません.これがまた別のグループにアクセスする場合も同様に,ドメイン名dc=www,dc=test,dc=comをつけて表現しなければいけないわけです.これは使用するエントリーの基準(すなわちdc=www,dc=test,dc=com)が決まっているのなら冗長です.できればlinuxで言うところのカレントディレクトリからの相対アドレスのようにエントリーを表現できると嬉しいわけですが,当然LDAPにもそのような仕組みが備わっています.LDAPに於けるカレントディレクトリはベースサフィックスと呼ばれ,そこから相対的なエントリーをrdn (relative distinguish name)によって指定します.例えば,ベースサフィックスがdc=www,dc=test,dc=comで,rdnがou=peopleであれば,ou=people,dc=www,dc=test,dc=comを表現していることになります.

さてここでは,ベースサフィックスがdc=www,dc=test,dc=comのときに,rdnとしてuid=Tanaka,ou=peopleというエントリーがあった場合を考えましょう.LDAPはNISの代わりとして使用できるので,このuid=Tanaka,ou=peopleはlinuxのアカウント情報を内包することもできるはずです.linuxにログインするために必要な情報はいくつかありますが,ここではログインシェルの情報を例にとってどのように格納されるを説明します.

先程も言いましたが,それぞれのエントリーはディレクトリのようなものを表しています.したがって各ディレクにおけるファイルのようなものがあります.LDAPに於けるファイルとは,属性と属性値の組を指します.ここでややこしいのは,すでに出てきているou=peopleなども属性と属性値の組であるという点です.普通のLinuxのディレクトリ構造ではディレクトリとその中身が同一であるということはありえません.しかし,LDAPでは各ディレクトリの識別子としてディレクトリ内の要素が使用されるのです.

正しい理解のためにこれらは次のように説明できます.

図に示した通り,一番下のエントリ(ここではTanakaと書かれたやつ)は複数の属性と属性値を持ちますが,この内,識別子(dn:distinguish name)として使用されるのは,cn=Tanakaとなります.これはlinuxのユーザ管理では同じ名前のユーザ名が存在してはいけないということを考えれば非常に合理的であることがわかります.ここでdnとしてloginShellを使用してしまっては,同じシェルを使ってる人どうして区別できなくなり困ることが予想されます.

さて,各エントリーは属性と属性値を持つことはすでに説明しましたが,実際に使える属性にはどのようなものがあるのかはまだ説明していませんでした.LDAPでは,エントリーに割り当てることがかのうな属性は決まっており,ユーザが自由に決めることは出来ません.使える属性はエントリーに与えるobjectClassによって指定されます.objectClassはSQLなどにおけるスキーマを表しますが,LDAPの特徴としてobjectClass自体も属性として表現されます.例えば,先程cn=Tanaka,ou=peopleにはloginShellという属性がありましたが,これはデフォルトでは使用できません.cn=Tanaka,ou=peopleのエントリーのobjectClass属性に属性値としてposixAccountを指定する必要があります.これは裏を返せば,linuxのアカウント情報を表現する属性が一意に定まることになるので,LDAPによって認証する側にとっても都合がいい事が分かります.

使い方

すでに説明したとおり,結局はエントリーの属性値を追加したり変更することがLDAPにおける処理の殆どになります.ldapにはエントリーについて記述したldifというファイルを元にデータベースの編集を行います.例えば,ou=People,dc=www,dc=test,dc=comにuid=tanakaを追加したい場合には次のような内容のldifファイル作ります.

一番上のdnは識別子を表します.これは追加したいエントリーの名前を表しているわけです.またその後uid: tanakaからhomeDirectory: /home/tanakaまでの行は,エントリーの中身(各属性とその属性値)を表しています.見ればだいたい何を表しているかわかると思いますが,userPasswordだけは不思議な記号になっており,パスワードのようには見えません.これは元のパスワードがわからないようにハッシュ化されているためです.このようなldifファイルを作成してあとは,

とすればtanakaというユーザを追加できます.ここで,test.ldifは先ほど作成したldifファイルを表しています.あと,まだ説明していませんでしたが,LDAPには管理用ユーザが存在します.この管理用ユーザもLDAPによって管理され,ここではcn=admin,dc=www,dc=test,dc=comというエントリーで表されています(-Dオプションの引数).LDAPのデータベースを自由に改変できては困るので,この管理用ユーザを介してエントリの変更を行うことが決まっています.

NISからの移行方法(サーバ編)

LDAPからNISへの移行方法を説明します.ここではOSはdebianとし,すでに運用しているNISが存在しているとします.ここで説明する方法はローカルのユーザ(/etc/passwd)の情報を用いても同様に使えるので,特別NISに限った方法ではないことを断っておきます.

まず必要なパッケージをインストールします.

すると色々聞かれますが,とりあえず今ここでちゃんと設定してもしょうがないので,エンターを連打します.質問をやり過ごしたら,

で編集画面に入り,

を追加してください.ここで,BASEのところは上で説明したベースサフィックスになります.自分の設定したいようにドメインを指定してください.URIのところは自分のipアドレスを指定する必要があります.ネットワークのドメイン名でもいいですが,名前解決が正常に行われてるのかどうか確認するのがめんどくさいのでipのほうが楽です.

次に

とします.すると色々聞かれるのでここ適切に答えます.
– OpenLDAPサーバの設定を省略しますか? → いいえ
– DNSドメイン名は? → ドメイン名を入力
– 組織名は? → これはベースdnの属性oの属性値になります
– 管理者用パスワード → 適当に決めてください
– 利用するデータベース → なんでも大丈夫です
– slapdをパージ(削除)した時に,データベースも消しますか? → はい(残す意味はあんまりない気がする)
– 古いデータベースを残しますか? → お好きで
– LDAPのv2を使いますか? → 古いマシンがあれば「はい」.一新するなら「いいえ」

以上で,LDAPの下地は出来たはずです.つぎに,linuxのユーザを管理するためのou=People,dc=www,dc=test,dc=com(dc=www,dc=test,dc=comは自分のさっき設定したやつに合わせて)とグループ用のou=Group,dc=www,dc=test,dc=comを作ります.そのために次のbase.ldifを作成します.

これを

で適用します.この時,LDAPのパスワードを聞かれますが,これは先程のLDAP用の管理者パスワードになります.またcn=admin,dc=www,dc=test,dc=comはdpkg-reconfigureのときに,自動で作られています.

次に,NISのユーザとgroupからldifを作る必要があります.ただしこれは数が膨大で大変です.そこで,自動生成するためのツールであるmigrationtoolsを使います.そのために

として,

の部分を

に変更してください.その後は,

としてください.すると/tmp/ldap_workにpasswd.ldifとgroup.ldifが作成されるはずです.ここで,sudoがないとパスワードがちゃんと書き込まれないので注意してください(/etc/shadowや/etc/gshadowがルート権限がないとアクセス出来ないため).あとは,これらを先程と同様に

で適用すれば終わりです.

NISからの移行方法(クライアント編)

まず必要なパッケージをインストールします.

すると色々聞かれますが,とりあえず今回は無視して適当にエンターを連打してください.これは,初回のインストール時での質問ではうまく設定してくれないという既知の問題があるため,エンターを連打してやり過ごします.二回目以降ではうまくいくことがわかっているので

を実行して,もう一度質問してもらいます.以下のように答えてください.
– LDAPサーバのURI: ldap://サーバのIPアドレス
– 検索ベースの識別名: dc=www,dc=test,dc=com
– LDAPプロトコルのバージョン: さっきサーバで指定したやつ
– LDAPデータベースはログインを必要としますか?:いいえ
– rootへの特別なLDAP権限?:はい
– オーナのみ設定ファイルの読み書きができるようにしますか?:はい
– rootのLDAPアカウント:cn=admin,dc=www,dc=test,dc=com
– 管理用パスワード:さっき設定したパスワード
– LDAPサーバのURI: ldap://サーバのIPアドレス
– 検索ベースの識別名: dc=www,dc=test,dc=com
– LDAPプロトコルのバージョン: さっきサーバで指定したやつ
– LDAP管理アカウントがローカルのrootのように振る舞うことを許しますか?:はい
– LDAPデータベースはログインを必要としますか?:いいえ
– rootのLDAPアカウント:cn=admin,dc=www,dc=test,dc=com
– 管理用パスワード:さっき設定したパスワード
– 使用するハッシュ:crypt
– 有効化するPAMプロファイル:必要なものを選択して了解
答え終わると色々設定してくれますが,重要なファイルである/etc/ldap/ldap.confがうまくやってくれていないので,これを編集して

を加えます.
次に/etc/nsswitch.confを編集します.

最後に/etc/pam.d/common-password を開いて,

のuse_authtokを削除します.これで設定完了です.

内容についてどう思いますか?
  • いいね (3)
  • だめ (0)

conemuでWSL使用時に256色使用する

罠だらけだったので備忘録.

手順

基本的なやり方は,公式ページのとおり.
ただ,なかなかうまくいかないので,自分の方法を示す.

conemuでWSL(Windows Subsystem for Linux:BoW)を直接使用した場合は256colorにならない.ただしcygwinを通すと256色にできるので,cygwinとWSLのブリッジ(wslbridge)を使用する.
ただし当然,これを起動するためにはcygwinが必要だが,WSLを使っているのにcygwinを入れるのは何か違う.そこですでにビルドされたものを使用する.それはここからダウンロードできる.インストーラを実行すると,デフォルトでC:\Users\username\AppData\Local\wslttyにインストールされる.

また,conemuでwslbridgeを利用するのにconemu-cyg64.exeも必要となる.それはここからダウンロードする.
7zを展開すると,conemu-cyg64.exeが手に入るので,これを先程のwslttyのbinフォルダに突っ込む(C:\Users\username\AppData\Local\wsltty\bin).

ここまでくれば必要な実行ファイル類は全て揃う.
次にC:\Users\username\AppData\Local\wsltty\bin\wsl.cmdを次の内容で作成.

この部分は,公式ページと少し違うので注意.

最後に,ConEmuのSettingsから,Startup → Tasksで{Shells::WSL}を作り,

を実行コマンドに指定すればok.

このタスクを実行すれば無事256色になっているはず.

内容についてどう思いますか?
  • いいね (5)
  • だめ (0)

vncserver

vncserverを使おうと思ってDebian(stretch)でtiger vncを入れて動かしてみたらクライアントからつながらず非常に困った。ほかのいろいろなサイトを見てもこれといった解決策が見つからず、そもそもポートが開いているのか確認したらlocalhostからしか繋げられない状態になっていた。これについて調べてみるとsshのポートフォワーディングで解決しようとしている例が多くヒットした。しかしローカルネットワークで使うだけなのにそんなことをいちいちするのはめんどくさすぎる。どうにかならないものかと思っていたら、どうやらvncserverコマンドがスクリプトであることを知った。ならばと思い中身を開いてみるとどうやら-localhostオプションにはyes/noの二つのオプションが指定できることが判明し、物は試しと-locahost noと指定して起動させると外部から繋げられるようになった。

バグなのかデフォルト動作が変わったのかわからないが、勘弁してほしい。

備忘録

内容についてどう思いますか?
  • いいね (0)
  • だめ (0)

BoWで音を鳴らす

Windowsの次の大型アップデートはCreators Updateというらしい.このCreators Updateでは様々な変更がなされているらしいが,今回注目したいのはBash on Windows(BoW)である.今までは日本語が不自然に切れてしまったり,ちょっとしたことで落ちてしまったりと微妙な感じだったが,今回のアップデートでは随分完成度が高くなるとのことである.

この新しいBoWがどの程度の完成度なのか非常に気になったので,試しに最新のビルド(番号は忘れた)をインストールして試してみることにした.インストールした直後はなぜかWindowsが不審な動きをして,非常に焦ったが時間が立つと勝手に治っていつもどおりの状態になった(よくわからない).次にBoWを起動して使ってみると,確かに今までと比べて色んな所が改善されており,これならある程度常用に耐えられるかもしれないと感じるまでになっていた.しかし,残念ながら音を流すことができない.私としては音声ファイルを再生して確認したい場面が多いため,これは非常に困る(音声関係もやっているので).そこでどうにか音を流す方法を調べたところ発見できたので備忘録として残しておこうと思う.

まずlinuxで音を流すといえばpulse audioを使うのが標準的だろう.ただしBoWはホストのオーディオデバイスを叩くことができない.そこでネットワーク経由でデータをホスト側に転送する方法が考えられる.具体的にはWindows用のpulse audioサーバを用意し,そこにBoW側のpulse audioを接続する形だ.この方法であればネットワークつながっていさえすれば音を流せるはずである.ここではその設定の詳細は次のサイトを参考にした.

http://nishio.hateblo.jp/entry/20111215/1323962652

さてこれに合わせて設定を行ったわけだが,残念ながらうまくいかない.

どうやら内部のpulseaudio側でクラッシュしているようだ.これをどうにか解決したいところである.そこでgoogleで調べると次のURIを発見した.

https://github.com/Microsoft/BashOnWindows/issues/486

これに従えばpulseaudioのソースコードを修正することで起動させることができるらしい.そこでまずはpulseaudioのソースコードをgitを使って手に入れる.

つぎにsrc/pulsecore/mutex_posix.hを編集し,23行目あたりを次のように編集する.

これで./autogen.shと言いたいところだが,実行したところ私の環境ではエラーが出てしまった.どうやらlibtoolのバージョンに伴うエラーのようだが,そもそも必要なバージョンより新しいものが入っているのでこれはおかしい.そこでこの部分をコメントアウトした(もっといい解決方法がある気がする…).具体的にはconfigureの10206行目にある

の部分である.コメントアウトできたら./autogen.shをする.もしエラーが出たら,基本的にパッケージ絡みのエラーだと思われるので必要なパッケージをインストールしまくる.必要なパッケージはエラーメッセージで検索すればわかるだろう../autogen.shが成功したら,次に下記のコマンドを打ち込む.

これでインストールは終了である.

さてここまでやって先程と同様にvlcを起動してもうまくいかない.なぜならvlc側でロードされる動的ライブラリはあくまで標準ライブラリのpulse audioのものであって,今回用意したものではないからだ.そこで次の環境変数を設定することで動的ライブラリをすり替える.

これをした後にvlcを利用するとうまくいくことが確認できる.めでたしめでたし.

 

内容についてどう思いますか?
  • いいね (0)
  • だめ (0)

VCSのエラー

verilogエミュレータとして有名なSynopsysのVCSだが,次のようなエラーが出て実行できないバグに出会った.

一体何が起こったのかと思いきや,gccの引数を見たところリンカに渡すファイルの順番が正しくないことが原因であることがわかった.そこで

vcs -LDFLAGS -Wl,-no-as-needed ~~~

という風にリンカのオプションに-no-as-neededを加えるようにしたらうまく動作した.

備忘録

内容についてどう思いますか?
  • いいね (0)
  • だめ (0)

sptkのwav2rawのエラー

wav2rawを使おうとしたら

uid: Undefined variable.

というエラーが出た.

よくわからないがどうやらuidという変数がないことを怒られていることがわかるので

export uid=$UID

をしたら動作した.

備忘録

内容についてどう思いますか?
  • いいね (0)
  • だめ (0)