<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
     xmlns:content="http://purl.org/rss/1.0/modules/content/"
     xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
     xmlns:atom="http://www.w3.org/2005/Atom"
     xmlns:dc="http://purl.org/dc/elements/1.1/"
     xmlns:wfw="http://wellformedweb.org/CommentAPI/"
     >
  <channel>
    <title>mojavy.com</title>
    <link>http://mojavy.com/blog</link>
    <description></description>
    <pubDate>Fri, 12 Jul 2013 19:15:50 GMT</pubDate>
    <generator>Blogofile</generator>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>ptraceを駆使してscreenifyっぽいことをするreptyrがすごい</title>
      <link>http://mojavy.com/blog/2013/07/12/reptyr/</link>
      <pubDate>Fri, 12 Jul 2013 19:15:50 JST</pubDate>
      <category><![CDATA[C]]></category>
      <category><![CDATA[linux]]></category>
      <guid isPermaLink="true">http://mojavy.com/blog/2013/07/12/reptyr/</guid>
      <description>ptraceを駆使してscreenifyっぽいことをするreptyrがすごい</description>
      <content:encoded><![CDATA[<p>reptyrというおもしろいものをみつけたのでご紹介</p>
<h2 id="reptyr">reptyr とは</h2>
<p>reptyrとは"re-ptying"するためのプログラムで、起動中のプロセスを新しい別のターミナルにもってくることができます。
例えば、うっかりscreenやtmuxの外で起動してしまった長い時間のかかるバッチ処理を、起動したままscreenの中にもってくることができます。</p>
<p><a href="https://github.com/nelhage/reptyr">https://github.com/nelhage/reptyr</a> </p>
<h2 id="_1">使い方</h2>
<div class="pygments_borland"><pre><span class="nv">$ </span>reptyr PID
</pre></div>

<p>現在のターミナル内にもってきたいプロセスのpidを引数にします。
attach後は、そのプロセスの入出力は^Cや^Zも含めて新しいターミナル側を向きます。</p>
<h2 id="screenify">それscreenifyでできるよ</h2>
<p>screenifyと呼ばれるスクリプトが昔からあって、それはgdbつかって似たようなことをやってるらしいです。
でもreptyrならもっとうまくできます。</p>
<p>例えば従来のscreenifyには以下のような問題がありました。</p>
<ul>
<li>screenifyでattachしたプロセスは、元のターミナルから入力をうけつけてしまう</li>
<li>ncursesをつかってるプログラムをscreenifyすると、そのプログラムはwindowのリサイズがとれなくなる</li>
<li>screenifyした新しいターミナルでは^Cがきかない</li>
</ul>
<p>reptyrはこういった問題を全部解決できます。</p>
<h2 id="_2">移植性</h2>
<p>reptyrは対象プロセスを操作するのにptraceをつかっているのでLinuxに強く依存しており、Linuxだけをサポートしています。
SolarisやBSDに移植することも技術的には可能ですが、現状はプラットフォーム固有の部分を抽象化するようにはデザインされていないようです。</p>
<p>reptyrは現状ではi386, x86_64, ARMをサポートしています。他のアーキテクチャへの対応はarch以下に対応コードを追加すれば比較的容易です。</p>
<h2 id="ptrace_scope-on-ubuntu-maverick-and-up">ptrace_scope on Ubuntu Maverick and up</h2>
<p>Ubuntu Maverick以降ではptraceの機能がデフォルトで無効になっています。
以下コマンドで一時的に有効にできます。</p>
<div class="pygments_borland"><pre><span class="nv">$ </span><span class="nb">echo </span>0 &gt; /proc/sys/kernel/yama/ptrace_scope
</pre></div>

<p>rootで<code>/etc/sysctl.d/10-ptrace.conf</code>を編集すると永続的に変更できます。また<code>ptrace_scope</code>に関する詳細な説明もここに書いてあります。</p>
<h2 id="_3">どうやってるの？</h2>
<p>ソースを追ってみたところ以下のような処理をしているようです。</p>
<ol>
<li>reptyrプロセス側でptyをつくる</li>
<li>attach対象のプロセスのttyのtermios設定をptyにコピーする</li>
<li>ptraceで対象プロセスをattachしてレジスタ内容を一旦退避</li>
<li>attachしたプロセス側でmmapし、そこにreptyrプロセス側でつくったptyをコピー</li>
<li>attachしたプロセス側でコピーしたptyをopenし、setsid〜ioctlでそこに制御端末を割り当てる</li>
<li>attachしたプロセス側でdup2して入出力をttyに向ける</li>
<li>レジスタ内容を復元、後始末してptraceをdetach</li>
</ol>
<p>reptyrのキモは5の制御端末をptyに割り当てるところで、これをすることによって従来のscreenifyの問題が回避できます。</p>
<p>しかし、単に<code>ioctl</code>の<code>TIOCSCTTY</code>するだけではうまくいかないのでちょっとしたトリックが必要です。詳細は<a href="http://blog.nelhage.com/2011/02/changing-ctty/">http://blog.nelhage.com/2011/02/changing-ctty/</a> に解説があります。
reptyrの作者は自力でこの方法を思いついたそうですが、同様のテクニックは <a href="https://github.com/ThomasHabets/injcode">injcode</a> や<a href="http://www.ohloh.net/p/neercs">neercs</a> でも使用されているそうです。</p>
<h2 id="reptyr_1">reptyrってどう読むの？</h2>
<p><code>repeater</code>のように発音してもいいけど曖昧なので<code>re-P-T-Y-er</code> (たぶんリ・ピーティーワイアー)のように発音してもよいそうです。</p>
<h2 id="_4">制約</h2>
<ul>
<li>backgroundにしたときは前のターミナルでbgやfgを実行する必要があります。background制御はshellがやっているので、これを直すにはshell側に手をいれる必要があります。</li>
<li>現状では子プロセスがあるプロセスはattachできません</li>
</ul>
<h2 id="_5">類似のもの</h2>
<ul>
<li><a href="https://github.com/ThomasHabets/injcode">injcode</a> </li>
<li><a href="http://www.ohloh.net/p/neercs">neercs</a> </li>
</ul>
<h2 id="_6">参考</h2>
<ul>
<li><a href="http://blog.nelhage.com/2011/01/reptyr-attach-a-running-process-to-a-new-terminal/">http://blog.nelhage.com/2011/01/reptyr-attach-a-running-process-to-a-new-terminal/</a> </li>
<li><a href="http://blog.nelhage.com/2011/02/changing-ctty/">http://blog.nelhage.com/2011/02/changing-ctty/</a> </li>
<li><a href="http://blog.habets.pp.se/2009/03/Moving-a-process-to-another-terminal">http://blog.habets.pp.se/2009/03/Moving-a-process-to-another-terminal</a> </li>
</ul>
<h2 id="_7">まとめ</h2>
<p>reptyrは1000行くらいの小さなプログラムですが、なかなかおもしろいハックだと思うので興味がある方はソースを読んでみて下さい。</p>]]></content:encoded>
    </item>
    <item>
      <title>pythonのswigエクステンションからdebian packageをつくる手順メモ</title>
      <link>http://mojavy.com/blog/2013/02/27/building-python-debian-package/</link>
      <pubDate>Wed, 27 Feb 2013 23:46:03 JST</pubDate>
      <category><![CDATA[python]]></category>
      <category><![CDATA[debian]]></category>
      <category><![CDATA[linux]]></category>
      <guid isPermaLink="true">http://mojavy.com/blog/2013/02/27/building-python-debian-package/</guid>
      <description>pythonのswigエクステンションからdebian packageをつくる手順メモ</description>
      <content:encoded><![CDATA[<p><img alt="debian" src="/images/debian-200.png" /></p>
<p>注: 以下は古めの環境(Lenny or Squeeze)と古めのpython (2.5 or 2.6)をターゲットにしたときの手順なので、最新の環境では別な方法があるかもしれません。</p>
<h2 id="_1">目次</h2>
<div class="toc">
<ul>
<li><a href="#_1">目次</a><ul>
<li><a href="#1">1. 必要なパッケージをインストール</a></li>
<li><a href="#2-setuppy">2. setup.pyをかく</a></li>
<li><a href="#3">3. ビルド確認</a></li>
<li><a href="#4-debianize">4. debianizeする</a></li>
<li><a href="#5-deb">5. debをつくる</a></li>
<li><a href="#_2">その他ツール等</a></li>
</ul>
</li>
</ul>
</div>
<h3 id="1">1. 必要なパッケージをインストール</h3>
<ul>
<li>python-setuptools</li>
<li>python-all-dev</li>
<li>python-support</li>
<li>python-stdeb</li>
<li>swig</li>
<li>debhelper</li>
<li>devscripts</li>
<li>dh_make</li>
</ul>
<p>たぶんこれだけあれば大丈夫。(python-supportはdeprecatedらしいけどここでは無視)</p>
<h3 id="2-setuppy">2. setup.pyをかく</h3>
<p><code>apt-get source python-xxx</code>で適当なパッケージのソースをダウンロードして参考にするとよい</p>
<p>以下例</p>
<div class="pygments_borland"><pre><span class="c">#!/usr/bin/python</span>

<span class="kn">from</span> <span class="nn">setuptools</span> <span class="kn">import</span> <span class="n">setup</span><span class="p">,</span> <span class="n">Extension</span>

<span class="n">__version__</span> <span class="o">=</span> <span class="s">&quot;0.0.1&quot;</span>

<span class="n">setup</span><span class="p">(</span><span class="n">name</span>         <span class="o">=</span> <span class="s">&quot;yourext&quot;</span><span class="p">,</span>
      <span class="n">version</span>      <span class="o">=</span> <span class="n">__version__</span><span class="p">,</span>
      <span class="n">author</span>       <span class="o">=</span> <span class="s">&quot;Your Name&quot;</span><span class="p">,</span>
      <span class="n">author_email</span> <span class="o">=</span> <span class="s">&quot;yourname@example.com,</span>
      <span class="n">url</span>          <span class="o">=</span> <span class="s">&quot;http://example.com/python-yourext&quot;</span><span class="p">,</span>
      <span class="n">download_url</span> <span class="o">=</span> <span class="s">&quot;http://example.com/python-yourext-</span><span class="si">%s</span><span class="s">.tgz&quot;</span> <span class="o">%</span> <span class="n">__version__</span><span class="p">,</span>
      <span class="n">description</span>  <span class="o">=</span> <span class="s">&quot;yourext client library for python&quot;</span><span class="p">,</span>
      <span class="n">long_description</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="s">&#39;README.md&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">read</span><span class="p">(),</span>
      <span class="n">license</span>      <span class="o">=</span> <span class="s">&quot;LGPL&quot;</span><span class="p">,</span>
      <span class="n">platforms</span>    <span class="o">=</span> <span class="p">[</span><span class="s">&quot;Platform Independent&quot;</span><span class="p">],</span>
      <span class="n">classifiers</span>  <span class="o">=</span> <span class="p">[</span>
        <span class="s">&quot;Development Status :: 5 - Production/Stable&quot;</span><span class="p">,</span>
        <span class="s">&quot;Intended Audience :: Developers&quot;</span><span class="p">,</span>
        <span class="s">&quot;License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)&quot;</span><span class="p">,</span>
        <span class="s">&quot;Operating System :: OS Independent&quot;</span><span class="p">,</span>
        <span class="s">&quot;Programming Language :: Python&quot;</span><span class="p">,</span>
        <span class="s">&quot;Topic :: Software Development :: Libraries :: Python Modules&quot;</span>
      <span class="p">],</span>
      <span class="n">ext_modules</span>  <span class="o">=</span> <span class="p">[</span>
        <span class="n">Extension</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s">&#39;yourext&#39;</span><span class="p">,</span>
                  <span class="n">sources</span><span class="o">=</span><span class="p">[</span><span class="s">&#39;path_to_swig/yourext.i&#39;</span><span class="p">],</span>
                  <span class="n">include_dirs</span><span class="o">=</span><span class="p">[</span><span class="s">&#39;path_to_lib/include&#39;</span><span class="p">],</span>
                  <span class="n">library_dirs</span><span class="o">=</span><span class="p">[</span><span class="s">&#39;path_to_lib/lib&#39;</span><span class="p">],</span>
                  <span class="n">libraries</span><span class="o">=</span><span class="p">[</span><span class="s">&#39;yourlibrary&#39;</span><span class="p">],</span>
                  <span class="n">define_macros</span><span class="o">=</span><span class="p">[(</span><span class="n">FOO_BAR</span><span class="p">,</span> <span class="mi">123</span><span class="p">),</span> <span class="p">(</span><span class="n">DEBUG</span><span class="p">,</span> <span class="bp">None</span><span class="p">)],</span>
                  <span class="n">extra_compile_args</span><span class="o">=</span><span class="p">[</span><span class="s">&#39;-std=gnu99&#39;</span><span class="p">,</span> <span class="s">&#39;-Wextra&#39;</span><span class="p">],</span>
                  <span class="p">)</span>
      <span class="p">],</span>
      <span class="n">py_modules</span> <span class="o">=</span> <span class="p">[</span><span class="s">&#39;pure_python_module_name&#39;</span><span class="p">,</span> <span class="s">&#39;foo.bar&#39;</span><span class="p">],</span>
      <span class="n">include_dirs</span> <span class="o">=</span> <span class="p">[</span><span class="s">&#39;&#39;</span><span class="p">],</span>
<span class="p">)</span>
</pre></div>

<ul>
<li>ext_modulesの中にExtensionをかく
<ul></li>
<li>Extension.sources にはswigの定義ファイルを直接指定できる</li>
<li>Extension.include_dirs, Extension.library_dirs, Extension.librariesはそれぞれgccでいう<code>-I, -L, -l</code>の値</li>
<li>Extension.define_macrosはタプルで渡す。上の例だと <code>-DFOO_BAR=123 -DDEBUG</code> の意味</li>
<li>Extension.extra_compile_args はその他のコンパイルオプション
</ul></li>
<li>platforms, classifiersの内容はpython-cjsonあたりからコピーした</li>
<li>pure pythonの部分はpy_modulesにモジュール名を列挙する。パスではない</li>
<li>swigが生成した<code>.py</code>ファイルをpy_modulesに含める汎用的な方法は見つからなかった。(必要な場合はスクリプトでinclude_dirsにコピーすることで対応できる)</li>
</ul>
<h3 id="3">3. ビルド確認</h3>
<p>以下コマンドでpython extのビルドを確認する。成功すると、buildディレクトリ以下に共有ライブラリが生成される</p>
<p><code>python setup.py build</code></p>
<h3 id="4-debianize">4. debianizeする</h3>
<p>以下コマンドでdebianパッケージに必要なファイルを生成する。このときegg-info等も生成される</p>
<p><code>python setup.py --command-package=stdeb.command debianize --force-buildsystem=True</code></p>
<h3 id="5-deb">5. debをつくる</h3>
<p><code>debuild -uc -us</code></p>
<p><code>-uc -us</code>は署名を省略するためのオプション。</p>
<p>成功すると、親ディレクトリにdebファイルができてるはず</p>
<h3 id="_2">その他ツール等</h3>
<ul>
<li>dupload: リポジトリにアップロードするためのもの</li>
<li>dlocate: <code>dlocate -S filename</code> のようにすればそのファイルを含むパッケージを調べることができる</li>
<li>cdbs: debianパッケージを作成するための別なやりかた(?)。 ちゃんとしらべてない</li>
</ul>]]></content:encoded>
    </item>
    <item>
      <title>おやつの時間をお知らせしてくれるUnixコマンド：at teatime (他...)</title>
      <link>http://mojavy.com/blog/2013/01/08/favorite-linux-command/</link>
      <pubDate>Tue, 08 Jan 2013 20:30:00 JST</pubDate>
      <category><![CDATA[unix]]></category>
      <category><![CDATA[tips]]></category>
      <category><![CDATA[linux]]></category>
      <guid isPermaLink="true">http://mojavy.com/blog/2013/01/08/favorite-linux-command/</guid>
      <description>おやつの時間をお知らせしてくれるUnixコマンド：at teatime (他...)</description>
      <content:encoded><![CDATA[<p><img alt="banana" src="/images/banana-200.png" /></p>
<p><a href="http://clippy.in/b/YJLM9W">Favorite Linux Commands(http://clippy.in/b/YJLM9W)</a> で紹介されてたコマンドのうち知らなかったものをメモ。</p>
<h2 id="at">at</h2>
<p>入力されたコマンドを指定されたタイミングで実行するようにスケジュールする。
cronに登録するほどでもない単発のコマンドを実行したいときとかにつかう。
時間の指定には現在の時刻からの経過時間や絶対時間の他にteatimeやmidnightといった文字列もつかえる。
ちなみにteatimeは午後4時。
出力先を指定しなければコマンドの出力はcronと同じようにメールにとぶ。$TTYにリダイレクトしてやればコマンドを実行した端末に表示させることもできる。</p>
<p>例</p>
<div class="pygments_borland"><pre>echo &quot;echo おやつの時間です &gt; $TTY&quot;| at teatime
echo &quot;echo はろー &gt; $TTY&quot; | at now + 3 minute
</pre></div>

<h2 id="mtr">mtr</h2>
<p>tracerouteとpingをあわせたようなもの。tracerouteより表示がみやすい。
ネットワークのどこで時間がかかってるのか一目でわかる。</p>
<p>例</p>
<div class="pygments_borland"><pre>mtr mojavy.com
</pre></div>

<h2 id="column">column</h2>
<p>入力テキストをいい感じのカラム表示にフォーマットしてくれる。
縦に長い出力するコマンドとか、そのままだと出力がみづらいときとかにつかう。</p>
<p>例</p>
<div class="pygments_borland"><pre>gem list | column
mount | column -t
grep -v &#39;^#&#39; /etc/apt/sources.list | column -t
</pre></div>

<h2 id="reset">reset</h2>
<p>端末をリセットする。
うっかりバイナリファイルをcatとかしてしまって端末が壊れてしまった場合に端末を閉じずに復帰できる。</p>
<h2 id="sshfs">sshfs</h2>
<p>ssh経由でリモートのファイルシステムをマウントできる。</p>
<p>例</p>
<div class="pygments_borland"><pre>sshfs name@server:/path/to/dir /path/to/mount/point
fusermount -u /path/to/mount/point  # unmount
</pre></div>

<h2 id="_1">その他</h2>
<p>以下はコマンド自体の機能ではないけど覚えておくと便利かもしれないもの</p>
<h3 id="curl-ifconfigme">curl ifconfig.me</h3>
<p>ifconfig.meというサイトがある。自分のグローバルIPがわかる。</p>
<h3 id="dig-short-txt-wzxhzdk5wpdgcx">dig +short txt <keyword>.wp.dg.cx</h3>
<p>dnsクエリでwikipediaのエントリーがみれる。</p>
<p>例</p>
<div class="pygments_borland"><pre><span class="nv">$ </span>dig +short txt banana.wp.dg.cx
<span class="s2">&quot;Banana is the common name for herbaceous plants of the genus Musa and for the fruit they produce. It is one of the oldest cultivated plants. They are native to tropical South and Southeast Asia, and are likely to have been first domesticated in Papua New &quot;</span> <span class="s2">&quot;Guinea. Today, they are cultivated throughout the tropics. They are grown in at least 107 countries, primarily for their... http://en.wikipedia.org/wiki/Banana&quot;</span>
</pre></div>]]></content:encoded>
    </item>
    <item>
      <title>pacoを導入</title>
      <link>http://mojavy.com/blog/2012/10/16/paco/</link>
      <pubDate>Tue, 16 Oct 2012 18:30:00 JST</pubDate>
      <category><![CDATA[paco]]></category>
      <category><![CDATA[linux]]></category>
      <guid isPermaLink="true">http://mojavy.com/blog/2012/10/16/paco/</guid>
      <description>pacoを導入</description>
      <content:encoded><![CDATA[<p>今さらだけどpacoを導入した。</p>
<p><a href="http://sourceforge.net/projects/paco/files/paco/2.0.9/">http://sourceforge.net/projects/paco/files/paco/2.0.9/</a> から最新のパッケージをダウンロード、展開して以下コマンドでインストール。gpacoは使わないと思うので--disable-gpacoした。</p>
<div class="pygments_borland"><pre>./configure --disable-gpaco
make <span class="o">&amp;&amp;</span> sudo make install
sudo make logme
</pre></div>

<p>何かをインストールする際は以下のようにする。</p>
<div class="pygments_borland"><pre>sudo paco -D make install
</pre></div>

<p>make install の部分は、bash install.shとかなんでもいい。</p>
<h1 id="_1">参考</h1>
<ul>
<li><a href="http://d.hatena.ne.jp/rx7/20081011/p2">http://d.hatena.ne.jp/rx7/20081011/p2</a></li>
<li><a href="http://paco.sourceforge.net/index.html">http://paco.sourceforge.net/index.html</a></li>
</ul>]]></content:encoded>
    </item>
  </channel>
</rss>
