シェルで標準出力と標準エラー出力を入れ替える

$ command3>&2 2>&1 1>&3 | …

または

$ var=`command 3>&2 2>&1 1>&3`

とすると STDOUT と STDERR を入れ替えることが出来ます。

$ err=`grep “Tarou” address1 address2`
address1: Tarou 090-xxxx-xxxx
$ echo $err
grep: address2: No such file or directory

 
参考:
いずれもオンライン書籍です。
Swap Standard Output and Standard Error(UNIX POWER TOOLS)
I/O Redirection(Advanced Bash Shell Scripting Guide)

PHPで任意のファイルデスクリプタを開く

PHP には fdopen がないので、子プロセスについては /dev/fd/<FD番号> で代用してます。
PHP の機能ではありませんが。。

<?php
// child.php: 子プロセス(parent.php から実行される)
$fd = 4; // 親プロセスとのやり取りに使うファイルデスクリプタ(0:stdin, 1:stdout, 2:stderr)
$fdfile = “/dev/fd/$fd”;
if(!file_exists($fdfile)){
   die(“ファイルデスクリプタが開かれていません”);
}
 
$pipe = fopen($fdfile, “r”);
while(!feof($pipe)){
  echo fread($pipe, 1024);
}
fclose($pipe);

 

<?php
// parent.php: 親プロセス
$fd = 4; // 子プロセスとの通信に使うファイルデスクリプタ
$fp = proc_open(“php child.php”, array(
  $fd=>array(‘pipe’, r),
),$pipes);
 
fwrite($pipes[$fd], “Hello world!!”);
fclose($pipes[$fd]);
 
proc_close($fp);

 
FreeBSD の場合、標準では /dev/fd に 0,1,2 しかないため動作しません。
次のようにしてfdescfs を /dev/fd にマウントすればプロセスごとのファイルデスクリプタを自動作成してくれるようになります。

# echo “fdescfs /dev/fd fdescfs rw 0 0” >> /etc/fstab
# mount /dev/fd

または /dev/fd を使わない実装に置き換える事でも動作します。
この場合、ファイルデスクリプタが開いているかの確認には fstat [-p PID] を使うといいかもしれません。

// child.php: FreeBSD で devfs を使っている場合の代替実装。
$fd = 4;
$pipe = popen(‘cat < &'.$fd, 'r');
echo fread($pipe, 1024)
pclose();

PHPのproc_open の落とし穴

http://d.hatena.ne.jp/ichii386/20071116/1195153132
 
proc_open()の説明に書いてある例通りやると問題があるので [[stream_select()|]http://jp.php.net/manual/ja/function.stream-select.php] をあわせて使いましょう、という話。
一つのストリームを読み書きしてる間に他のストリームからの入力がたまるとバッファがいっぱいになってしまい、そこで書き出し側の処理がブロックしてしまう可能性がある。
stream_select を使うと、複数のストリームの中から入出力要求がきているストリームのみを選択して読み書きすることが出来ると。
 

// http://d.hatena.ne.jp/ichii386/20071116/1195153132 から引用:
$stdout = $stderr = ”;
while (feof($pipes[1])= false || feof($pipes[2]) = false) {
    $ret = stream_select(
        $read = array($pipes[1], $pipes[2]),
        $write = null,
        $except = null,
        $timeout = 1
    );
    if ($ret= false) {
        echo “error\n”;
        break;
    } else if ($ret
= 0) {
        echo “timeout\n”;
        continue;
    } else {
        foreach ($read as $sock) {
            if ($sock= $pipes[1]) {
                $stdout .= fread($sock, 4096);
            } else if ($sock
= $pipes[2]) {
                $stderr .= fread($sock, 4096);
            }
        }
    }
}

Windowsで「ファイル名を指定して実行」をランチャー化するカスタマイズ方法と起動コマンド一覧

http://it.kndb.jp/entry/show/id/146
 
4年くらい前から、この記事と同じようにファイル名を指定して実行(Windows+R)をランチャーとして使っています。
いちいちランチャーをインストールするより Windows の標準機能を使おうということで始めたもののこれが存外に便利。
「ファイル名を指定して実行」に慣れると Windows標準のコマンドも覚えられるし、引数対応のプログラムもフル活用できて一石二鳥、です。
 
既存のコマンドとかぶらないよう、自分ルールで頭に記号をつけたものをショートカットで作って使っています。
 
・ “+” から始まるものはディレクトリ(+bin でランチャー用ディレクトリ, +home でマイドキュメントなど)
・”@” から始まるものはプログラム短縮名(@f で firefox, @i で iexplorer(Internet Explorer), @e で Eclipse, @p で PuTTY, @n でテキストエディタ, @fz で FileZilla, @ooo で OpenOffice.org などなど)
 
とくにキーボード派にオススメです。おためしあれ。

FOMA Flashlite3.x をコピー禁止にする

DoCoMo 携帯では Flashlite 3.x からプロファイルでコピー禁止(転送禁止)を明示しないとファイル転送可能になりました。
 
SWFファイルの再配布を防止するには(携帯サイトを作ろう。)に詳しくまとめられています。
CS4 の場合は以下の手順で設定できるようです。

 (引用)
プロパティ→プロファイル→「編集」をクリック
FlashタブのSWF設定で「XMPメタデータを含める」にチェックが入っていることを確認し、「ファイル情報」をクリック
モバイルSWFタブの「フォーワードロック」にチェックを入れて「OK」をクリック

 
この記事では CS3 について詳しく書かれていませんが、CS3 の場合は標準ではXMPプロファイル設定ができないため、Adobe サイトから CDK をインストールする必要があります。
 
■ Flash CS3 Professional への Flashlite 3.0 CDK インストール手順
1. Adobe ダウンロードページから「Flash CS3 Professional 用 Flash Lite 3.0 アップデート」をダウンロードして fl_flashlite3_update.exe を実行し、プログラムに従ってインストールする。
 
2. Adobe Flash Lite for i-modeのウェブサイトから「Flash Lite 3.0 対応 NTT DoCoMo 携帯電話用 Adobe Flash CDK をダウンロード」を選択し、CDK(コンテンツ開発キット)をダウンロードする。
 →「Adobe モバイル デベロッパー プログラムに参加」のフォームが開きます。名前とメールアドレスが必須入力になっていますが、メール認証や会員登録もなく、ニュースレターの配信も任意なのでそれほど手間ではないです。適当にアドレスを入れて「続行」、を選択してください。この次のページでダウンロードできます。
 
3.ダウンロードしたファイル(flash_lite_3_0_image_cdk_jp.zip)を展開する。
この中に含まれるファイルのうち、「metadata_tool_readme_jp.pdf」が拡張機能の説明書、「モバイルメタデータ.swf」が拡張パネル本体です。
 
4.説明書の手順に従い「モバイルメタデータ.swf」を指定フォルダにインストールする。
swf を指定フォルダにコピーすることで、Flash CS3 Professional から拡張パネルとして利用できるようになります。
コピー先は OS によって異なり、それぞれ次のフォルダがコピー先になります。

■ Windows Vista PC:
…/Users/< ユーザ名>/AppData/Local/Adobe/Flash CS3/ja/Configuration/
WindowsSWF
■ Windows XP PC:
…/Documents and Settings/< ユーザ名>/Local Settings/Application Data/
Adobe/Flash CS3/ja/Configuration/WindowsSWF
■ Apple Mac:
…/Users/< ユーザ名>/Library/Application Support/Adobe/Flash CS3/ja/
Configuration/WindowsSWF

 
5.Flash CS3 Professional を開く。
既に開いている場合はインストールしたパネルを反映させるため、一度 Flash CS3 Professional を再起動してください。
 
6.Flash CS3 Professional で、コピー禁止させたい Flashlite 3.0 プロジェクトを開く。
インストールに成功していたら「ウィンドウ」メニューの「他のパネル」の項目に「モバイルメタデータ」が追加されています。
 
7.「ウィンドウ」メニュー→「他のパネル」→「モバイルメタデータ」を開く
「フォーワード・ロック」をチェック
 
8.右下の適用ボタン(レ点)を押して適用
 
9.Flashlite3.x としてパブリッシュ
 
以上です。

Linuxの/proc 以下を見て、メモリ利用状況を調査する(OOM Killer対策)

oom-killer からメモリ関係を追っていて気になったのでメモ。
procファイルシステム配下のトップレベルファイル(redhat.com)
 
・ /proc/meminfo
現在のメモリの使用状況を表示します。
核パラメータの詳細はこちら(Linuxカーネルメモ)
例:

$ cat /proc/meminfo
MemTotal: 10391204 kB
MemFree: 5276876 kB
Buffers: 436432 kB
Cached: 3746096 kB
SwapCached: 0 kB
Active: 3976932 kB
Inactive: 757892 kB
HighTotal: 9567104 kB
HighFree: 5034592 kB
LowTotal: 824100 kB
LowFree: 242284 kB
SwapTotal: 8385920 kB
SwapFree: 8385920 kB
Dirty: 96 kB
Writeback: 112 kB
AnonPages: 467276 kB
Mapped: 884892 kB
Slab: 137352 kB
PageTables: 224292 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
CommitLimit: 13581520 kB
Committed_AS: 2113328 kB
HighTotal: 9567104 kB
HighFree: 5034592 kB
LowTotal: 824100 kB
LowFree: 242284 kB
SwapTotal: 8385920 kB
SwapFree: 8385920 kB
Dirty: 96 kB
Writeback: 112 kB
AnonPages: 467276 kB
Mapped: 884892 kB
Slab: 137352 kB
PageTables: 224292 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
CommitLimit: 13581520 kB
Committed_AS: 2113328 kB
VmallocTotal: 116728 kB
VmallocUsed: 6884 kB
VmallocChunk: 109344 kB
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
Hugepagesize: 2048 kB

・ /proc/buddyinfo
 DMA, Normal, Highmem 領域ごとの空きメモリスロット(ページ単位)を表示します。
左から 1*4KB, 2*4KB, 4*4KB, 8*4KB, …, 4096*4KB(1ページ=4096バイトの場合) を1単位としたスロット数を表示していて、1行の合計がその領域の全空き容量になります。
例:

$ cat /proc/buddyinfo
Node 0, zone DMA 5 2 0 0 0 0 0 1 1 1 0
Node 0, zone Normal 209 104 20 5 2 1 0 0 1 1 0
Node 0, zone HighMem 6925 3038 1002 212 17508 8000 1164 274 118 9 633

 
・ /proc/zoneinfo
DMA, Normal, Highmem 領域ごとの詳細なメモリ使用状況を表示します。
例:

$ cat /proc/zoneinfo
Node 0, zone DMA // DMA 領域の情報(単位:ページ)
  pages free 905
        min 17
        low 21
        high 25
        active 2
        inactive 0
        scanned 0 (a: 21 i: 9)
        spanned 4096
        present 4096
・・・中略・・・
Node 0, zone Normal // Normal 領域の情報(単位:ページ)
  pages free 1305
        min 939
        low 1173
        high 1408
        active 625
        inactive 1889
        scanned 0 (a: 9 i: 0)
        spanned 225280
        present 225280
・・・以下略・・・

参考:
Linuxカーネルメモ

Flash SWFファイル仕様 – ActionScript の仕様詳細(SWF3,SWF4)

Flashlite 1.x で採用している ActionScript 1.0 (SWF3,SWF4) の SWF 仕様についてメモ。
シンプルなつくりですが、スタックなど後継の ActionScript2, AS3 の実装の根幹になる部分なので最新のバージョンの AS を理解する上でも参考になると思います。
 
これさえ読めばバイナリエディタや swfmill で ActionScript を1から記述できる、かもしれません。
 

SWF 仕様書ではチャンクの事をさして「タグ」と書いてあるのですが、XMLタグとの混同を避けるため、ここではチャンクと記述することにしました。
 
なお、swfmill で利用する際にタグ名とチャンク名で名前が変わっている場合があるため、swfmill で名前が変わるチャンクについては、End (swfmill:<EndAction>)のように、カッコ内にswfmillでのタグ名を表記しています。
 
 
■ アクション(ActionScript)はすべて DoAction チャンクの Actions フィールド(swfmill:<Actions>)に定義する。
SWF3, SWF4 では他の場所にアクションは書けません。
逆に DoAction の中にはアクションしか書けません。
分離されていて分かりやすいですね。
 
■ Actions フィールド(swfmill:<Actions>)は1バイトのヌル文字で終わる。
Actions フィールドはアクションの連続で構成され、0 個以上の任意の数のアクションを記述できます。
End フラグ(swfmill: <EndAction>)をあらわす1 バイトのヌル文字で終わります。
例:

DoAction チャンク(tag-type:12)
  Actions フィールド(0個以上のアクションを指定)
  {Action1}
  {Action2}
  {Action3}
  …
  End フラグフィールド(ヌル文字)

swfmill 例:

<DoAction>
 <Actions>
   <!– Action1 –>
   <!– Action2 –>
   <!– Action3 –>
   <!– : –>
   <EndAction />
 </Actions>
</DoAction>

 
■ アクションが実行されるのはフレームが表示される時。
どこで DoAction を定義したとしても、カレントムービークリップの現在のフレームが表示されるタイミングで実行されます。
つまり、DoAction で定義した時に処理されるわけではなく、その後最初に ShowFrame タグが現れた時にたまっていたアクションが一気に実行されます。
これはアクションスクリプト内でムービークリップ等を参照する場合、ShowFrame までに配置されていればよく、DoAction タグが現れた時点では何も存在してなくても問題ない、という事を意味します。
 
■ アクションは全てスタック方式で記述する。
SWF4 以降、アクション中の関数、式、およびそれらで使う式の左辺、式の右辺、関数の引数、メソッドの実行インスタンスなど全ての要素は LIFO(Last In First Out) のスタック方式で記述します。
例: 「 a=123; b = a + 15; 」 という2個の式を SWF4 のアクションチャンクで記述する。

DoAction
  ActionPush(Type:0) a // “a” をスタックに積む…stack1
  ActionPush(Type:0) 123 // “123” をスタックに積む…stack2
  ActionSetVariable // stack1,stack2 を取り出して stack1 = stack2 として評価( a = “123”;)
  ActionPush(Type:0) b // “b” をスタックに積む…stack1
  ActionPush(Type:0) a // “a” をスタックに積む…stack2
  ActionGetVariable // stack2 を取り出して変数 a の値を参照してスタックに積みなおす(a -> “123”) …stack2
  ActionPush(Type:0) 15 // “15” をスタックに積む…stack3
  ActionAdd // 直近の2スタック(stack2,stack3)を合算し、結果をスタックに積む(123 + 15 -> 138) … stack2
  ActionSetVariable // stack1, stack2 を取り出して stack1 = stack2 を評価(b = 138)
  End // アクション記述終了

swfmill の例:

<DoAction>
  <actions>
    <PushData>
      <items>
        <StackString value=”a”/>
      </items>
    </PushData>
    <PushData>
      <items>
        <StackString value=”123″/>
      </items>
    </PushData>
    <SetVariable/>
    <PushData>
      <items>
        <StackString value=”a”/>
      </items>
    </PushData>
    <PushData>
      <items>
        <StackString value=”b”/>
      </items>
    </PushData>
    <GetVariable/>
    <PushData>
      <items>
        <StackString value=”10″/>
      </items>
    </PushData>
    <AddCast/>
    <SetVariable/>
    <EndAction/>
  </actions>
</DoAction>

 
■SWF チャンク書式
SWF のチャンクはヘッダ部と本体から構成されます。
ヘッダ部は全てのチャンクで共通で、
・種類(Tag type)
・ヘッダを除くチャンクの長さ
の2要素からなります。
 
ヘッダを除いたチャンクの長さが63バイト以内の場合、以下の短縮書式で記述し、ヘッダのサイズは2バイトになります。
・種類(Tag type): 10ビット
・ヘッダを除くチャンクの長さ: 6ビット
 
ヘッダを除いたチャンクの長さが 64 バイトを越える場合、以下の書式で記述し、ヘッダのサイズは6バイトになります。
・種類(Tag type): 2バイト(UI16)
・ヘッダを除くチャンクの長さ: 4バイト(UI32)
 
■アクション書式
DoAction の Actions フィールド内に記述するアクションもチャンクの書式にならっていて、ヘッダ部とその他の部分に分かれています。
ヘッダ部の構成要素もチャンク同様
・種類(ActionCode/アクションコード): 1バイト(UI8)
・ヘッダを除くアクションの長さ: 2バイト(UI16)
の2要素からなります。ヘッダ部のサイズは 3バイトです。
 
ただしアクションコードが 0x80 未満のアクションはヘッダしか持たないため、長さを記述しません。
このときはヘッダのサイズは1バイトになります。
 


アクション一覧
 
■SWF3
SWF3 ではフレームの移動などムービークリップの基本操作が実装されました。
※SWF3 はスタック方式ではないため、引数が必要なアクションについてはフィールド部に記述します。
 
○ ActionNextFrame
次のフレームを再生後停止する。
ActionScript: nextFrame()
ActionCode: 0x04
 
○ ActionPreviousFrame
前のフレームを再生後停止する。
ActionScript: previousFrame()
ActionCode: 0x05
 
○ ActionPlay
現在の(次の)フレームから再生する。
ActionScript: play()
ActionCode: 0x06
 
○ ActionStop
現在のフレームの処理完了後停止する。
ActionScript: stop()
ActionCode: 0x07
  
○ ActionToggleQuality
表示品質を高⇔低に相互に切り替える。
ActionCode: 0x08
 
○ ActionStopSounds
再生している音をすべて停止する。
ActionScript: stopSounds()
ActionCode: 0x09
 
○ ActionGotoFrame
指定したフレームに移動する。
gotoAndPlay(), gotoAndStop() に数値を指定した場合に呼ばれる。
gotoAndPlay() と同じ動作を望む場合は ActionGotoFrame の後に ActionPlay を実行すればよい。
ActionScript: gotoAndPlay()
ActionCode: 0x81
Length: 2 固定
フィールド: frame=移動先フレーム番号(UI16)
 
○ ActionGotoLabel
指定したフレームに移動する。
gotoAndPlay() に文字列を指定した場合に呼ばれる。
ActionScript: gotoAndPlay()
ActionCode: 0x8C
フィールド: label=移動先フレーム名(文字列)
 
○ ActionWaitForFrame
ActionCode: 0x8A
Length: 3 固定
フィールド: フレーム番号(UI16), スキップするアクションの数(UI8)
 
○ ActionGetURL
指定したターゲットの内容を URL 先のデータに置き換える(HTML, SWF など)。
ActionScript: getURL()
ActionCode: 0x83
フィールド: URL(文字列), ターゲット(文字列)
 
○ ActionSetTarget
以降のすべてのアクションを指定したインスタンスで実行するよう変更する(例 SetTarget “../foo”)。
SetTarget “” のように空文字を指定すると現在のムービークリップに戻します。
ActionScript: tellTarget(){ … }
ActionCode: 0x8B
フィールド: ターゲット名(文字列)
 


■SWF4で追加されたタグ
SWF4 からスタック構造になり、条件分岐や演算子など基本的なプログラミング言語の機能が実装されました。
ただ型についてはまだまだ未実装な部分が多く、boolean は数値、数値は文字列として処理し、スタックに入れられます。文字列連結演算子が + ではなく add なのはこのためです。
 
□算術演算子
○ ActionAdd (swfmill:<AddCast>)
ActionScript: + 演算子
※SWF5 以降は ActionAdd2 (swfmill:<AddTyped>) に置き換え
 
○ ActionDivide (swfmill:<Divide>)
ActionScript: / 演算子
 
○ ActionMultiply (swfmill:<Multiply>)
ActionScript: * 演算子
 
○ ActionSubtract (swfmill:<Subtract>)
ActionScript: – 演算子
 
□関係演算子(数値比較)
○ ActionEquals
ActionScript: == 演算子
 
○ ActionLess
ActionScript: < 演算子
 
□論理演算子
○ ActionAnd
ActionScript: && 演算子
 
○ ActionNot
ActionScript: ! 演算子
 
○ ActionOr
ActionScript: || 演算子
 
□文字列操作
○ ActionStringAdd
※SWF5 以降は ActionAdd2 に置き換え
ActionScript: add 演算子
 
○ ActionStringEquals

○ ActionStringExtract
○ ActionStringLength
○ ActionMBStringExtract
○ ActionMBStringLength
○ ActionStringLess
 
□スタック操作
○ ActionPop
○ ActionPush
 
□型変換
○ ActionAsciiToChar
○ ActionCharToAscii
○ ActionToInteger
○ ActionMBAsciiToChar
○ ActionMBCharToAscii
 
□制御構造
○ ActionCall
 
○ ActionIf (swfmill: <BranchIfTrue>)
if 文の実装。条件に一致していたら指定バイト数アクション処理を飛ばす。
ActionScript: if( … ){ }
ActionCode: 0x9D
フィールド: BranchOffset=移動バイト数(-32768 から 32767 までの間の数値。ActionIf の次のアクションを0とする)
例: if( n < 5 ){ 処理1; }else{ 処理2 }; 処理3; をアセンブラで記述。

DoAction
  ActionPush “n”
  ActionGetVariable // 変数 n を展開
  ActionPush “5”
  ActionLess // n < 5 を判定し、結果をスタックに入れる
  ActionNot // スタックにいれた真偽値を「反転」
  ActionIf 123 // スタックに入れた値が真なら処理を ActionJump の次(123バイト先)まで飛ばす
  // (処理1 のアセンブラ) if(){ … } 内
  ActionJump 23 // 処理1の最後に到達する。ここにきたら処理2(23バイト分)を飛ばす。
  // (処理2 のアセンブラ) // else{ … } 内
  // (処理3 のアセンブラ) // 条件文の外の共通処理。
  End フラグ

例: swfmill での記述例

<DoAction>
 <actions>
  <PushData><items><StackString value=”n” /></items></PushData>
  <GetVariable/>
  <PushData><items><StackString value=”5″ /></items></PushData>
  <LessThanCast/>
  <LogicalNOT/>
  <BranchIfTrue byteOffset=”123″ />
  <!– 処理1 –>
  <BranchAlways byteOffset=”23″ />
  <!– 処理2 –>
  <!– 処理3 –>
  <EndAction/>
 </actions>
</DoAction>

 
○ ActionJump (swfmill:<BranchAlways>)
if 文のelse 部の実装。このアクションに到達した場合、無条件で指定バイト数アクション処理を飛ばす。
ActionScript: if .. else{ }
ActionCode: 0x99
フィールド: BranchOffset=移動バイト数(-32768 から 32767 までの間の数値。ActionJump の次のアクションを0とする)
 
 
□変数
○ ActionGetVariable
○ ActionSetVariable

[Linux] procmailrc でひとつの条件に複数のアクションを指定する

同じ条件で複数指定すると簡単に実現できます。

 :0
 * 条件A
 * 条件B
 アクション1
 
 :0
 * 条件A
 * 条件B
 アクション2

が、同じ条件が分散するのは宜しくない、ということで。

 :0
 * 条件A
 * 条件B
 {
     :0
    アクション1
    :0
    アクション2
 }

このように括弧を使うと複数のレシピをひとつのアクションとして扱うことができます。
 
参考:
Procmail How-To page

Flash をxmlから作れる便利な swfmill でさらに Flash Lite 1 の swf を扱えるようにしてみた

Klab さんのパッチで swfmill simple を扱った時に文字コードエラーが出る件で、解決パッチを作ってみました。
 
参考…2009-06-05 / swfmill – メモ。cp932まわり
 
このエラーは swfmill simple で <clip import=”file.swf” /> として flash をインポートする時、 file.swf が flashlite 1.x であり、その swf 内に日本語を含む場合にのみ発生します。
 
swf のインポートを処理する swft_document() で swf->xml に変換する処理でテキストエンコーディングが効いていないのが原因でした。
アドホックではありますが -e で与えた文字コードをインポートするパッチを当てたところ、無事エラーなく動作するようになりました。
 
swfmill simple テキストエンコーディング対応パッチ
 
Klab さんのパッチとあわせて適用してください(パッチ順序は問いません)。