新・日々録 by TRASH BOX@Eel このページをアンテナに追加 RSSフィード

2016-11-05

あえてbc(1)した話

たぶんまだまだ初級な小ネタ。

こんな感じに16進数(プレフィックスなし)のデータが並んでいるテキストファイルtest.datがあって:

00000000
00000001
0000000F
00000010
7FFFFFFF
80000000
FFFFFFFE
FFFFFFFF

これを元データ(32bit符号なし整数)としてちょっとした分析をしたかった(本来のデータは、もっと件数が多く、値もバラエティに富んでいる。ただし数値としてソート済みなのは同じ)。

したかったのだが、awk(1)とか、デフォルトで16進数を扱えなかった。恥かしながら、初めて気づいた……。

そこでbc(1)を使って10進数に変換してみた。

$ echo ibase = 16 | cat - test.dat
ibase = 16
00000000
00000001
0000000F
00000010
7FFFFFFF
80000000
FFFFFFFE
FFFFFFFF
$ echo ibase = 16 | cat - test.dat | bc
0
1
15
16
2147483647
2147483648
4294967294
4294967295
$ echo ibase = 16 | cat - test.dat | bc >test_dec.dat
$ _

これで、他のツールで扱いやすくなった。

bc(1)を使う手法は、テキスト処理で「力任せな計算式」を組み立ててしまえばよい、という点で、少々興味深い。

$ # 取り扱うデータはこんな感じ。
$ cat test_dec.dat
0
1
15
16
2147483647
2147483648
4294967294
4294967295
$ # 各データについて、2で割った値を求める(小数第二位まで表示)
$ sed '1s/^/scale = 2; /;s!$! / 2!' test_dec.dat
scale = 2; 0 / 2
1 / 2
15 / 2
16 / 2
2147483647 / 2
2147483648 / 2
4294967294 / 2
4294967295 / 2
$ sed '1s/^/scale = 2; /;s!$! / 2!' test_dec.dat | bc
0
.50
7.50
8.00
1073741823.50
1073741824.00
2147483647.00
2147483647.50
$ # 最初のデータを捨てる。
$ # 3番目以降のデータについて、2番目のデータとの差分を求める。
$ sed '1d;2s/^/n = /;3,$s/$/ - n/' test_dec.dat
n = 1
15 - n
16 - n
2147483647 - n
2147483648 - n
4294967294 - n
4294967295 - n
$ sed '1d;2s/^/n = /;3,$s/$/ - n/' test_dec.dat | bc
14
15
2147483646
2147483647
4294967293
4294967294
$ # 1つ前のデータとの差分を求める。
$ sed '1s/^/n = /;2,$s/^.*$/& - n; n = &/' test_dec.dat
n = 0
1 - n; n = 1
15 - n; n = 15
16 - n; n = 16
2147483647 - n; n = 2147483647
2147483648 - n; n = 2147483648
4294967294 - n; n = 4294967294
4294967295 - n; n = 4294967295
$ sed '1s/^/n = /;2,$s/^.*$/& - n; n = &/' test_dec.dat | bc
1
14
1
2147483631
1
2147483646
1
$ _

まあ、不正なデータが入力されない(処理するデータはエラーチェック済みで、不正値は取り除かれている)という前提があるからこそ可能な手法ではある。本質的にはサーバサイドのXSSと同じ危険性があるからなあ。

2016-10-31

grep(1)しない話

もう1つ、初級小ネタ。

DebianUbuntuで、あるパッケージがインストールされているか否か調べるのに、今までdpkg(1)とgrep(1)を組み合わせていた。

dpkg -l | grep acpi

ところで先日、dpkg(1)のmanを見たところ:

-l, --list package-name-pattern...

package-name-pattern」という怪しい文言が……。

dpkg --help」の内容も:

-l|--list [<pattern> ...]

pattern」! 実に怪しいな。

dpkg-query(1)のmanに:

Normal shell wildchars are allowed in package-name-pattern.

――と書かれていたので、*?[...]といった一般的なワイルドカードが使えるようだ。

dpkg -l 'acpi*'     # acpiで始まるパッケージを探す
dpkg -l '?awk'      # awkで終わる4文字のパッケージを探す
dpkg -l '[gm]awk'   # gawkかmawkを探す

ということで、grep(1)で引っかけたい対象がパッケージ名である場合に限り、シェルのパス名展開と同じワイルドカードでパターンを書けば、grep(1)が不要だと分かった。

もう「お前、何年Debianディストリビューション触ってんだよ!」的な事案である。Ubuntuとは8.04の頃からの付き合いだし、Debianも6.0が出る直前ぐらいから実験用に最小構成インストール仮想マシンを使ったりしていたのに、この体たらくである。

やっぱりmanを読まないとアカンなあ……しかしLinux(ないしPC-Unix)を常用していない兼業状態なので、安直にネットで拾った情報に頼ってしまう。どうしたものか。

cat(1)しない話

初級小ネタ。

例えばgrep(1)する際に、こんな感じのサンプルコードが示されることがある。

cat file.txt | grep foo

しかし個人的には次のほうが好みだ。

grep foo file.txt

せっかく引数でファイルを指定できるのだから、そちらを使いたい気分になるのだ。

tr(1)のように標準入力しか受け付けないコマンドや、wc(1)のようにファイルか標準入力かで出力が変化するコマンド(で、標準入力の場合の挙動の方が望ましいケース)では、リダイレクトを使う書き方をする。

tr [abc] [ABC] <file.txt
wc -l <file.txt

わざわざcat(1)を使ってテキストフィルタに流し込むのは、複数のファイルを連結した結果に対して何かを行いたい場合ぐらいだが、機会は少ない。

2016-10-24

ここ15年ぐらいの自作PCの変化

ここ最近、古いスリムタワー型PCの電源を交換したり、古いタワー型PCの中身を入れ替えてリストアしたりと、古い自作PCの中身を拝見する機会があった。そこで自作PCの変化のようなものにあらためて気づいたので、メモを残しておく。

ちなみに私は、ライトな自作PC趣味を始めて15年ぐらい。ガチの自作PCではなくライト、それもここ数年は「必要になったら情報を集める」というスタンスなので、最近の事情はあまり知らない。

オンボード化(それにともなうケース小型化)

昔と今とで大きく異なるのが、拡張カードの枚数。かつてはグラフィックカードサウンドカードLANカード(あとモデムか?)が必須だったが、段々とマザーボードに統合されていった。今では、拡張カードなし(全てオンボード)という構成は珍しくない。軽い3Dならオンボード(というかCPUと統合された)GPUでも十分だし、Gigabit LANポートにいたっては2つも付いているマザーボードさえある。

記憶が正しければ、オンボード化で真っ先に姿を消した拡張カードLANカードだったように思う。その次がサウンドカードなのだが、音の世界には根強いファンがいることもあり、サウンドカード自体は生き残っている(とはいえ外付けUSB音源が増えつつあるが)。グラフィックカードは、コンシューマ向けのメーカーこそAMDNVIDIA収束したものの、ハイエンドPCでは現役だ。

オンボード化が進むことで、ローエンドやミドルエンドのPCでは、拡張カードスロットが不要となっていった。要求スペック次第だが、マザーボードとしてmicroATXMini-ITXでも問題ないことが多い。マザーボードmicroATXMini-ITXなら、ケースも小さくてよい。拡張カードが不要なら、拡張カード取り付けに必要な空間を削ることも可能となるので、さらにケースを小型化できる。

ミドルタワーやスリムタワーのPCをリストアして、中身をMini-ITXにすると、何ともいえない気分になる。スッカスカやね。

光学ドライブの衰退(それにともなう5インチベイ省略?)

内蔵型光学ドライブ(CD/DVD/BDドライブ)も減ってきた。元より、USBの高速化が進んだことや、USBデバイスからのbootが問題なくなったこともあり、外付けUSB-DVDドライブなどに置き換わるかと思っていたのだが……。

音楽や映像のオンライン配信ソフトウェアダウンロード販売 or サブスクリプション購入化、USBメモリによるOSインストール――何というか、外付けドライブ云々の次元を飛び越えて、光ディスクの進退問題にまで至ってしまったようだ。内蔵型ドライブだけでなく外付けドライブも減っていきそうというか、すでに外付けドライブすらニッチ商品になりつつあるように思う。

PCケースに5インチベイが残っていた原因は内蔵型光学ドライブの存在なので*1光学ドライブが不要となれば5インチベイも不要となる気がする。もっとも、ATX電源グラフィックカードの大きさ(横幅)や、ケース内部での作業のしやすさなどの話があるので、ミドルタワーやミニタワーのケースがスリムになるとは思えないのだが。すでにスリムタワーとかがあるからなあ。

ところで、PCケースから内蔵型光学ドライブを取り外すのはよいのだが、取り外した後の蓋が無い。どうしたものか。

シリアルATA

内蔵デバイスシリアルATA化されたことで、接続用ケーブルがスリムになった。内蔵FDDも姿を消して久しいので、今ではIDEケーブルのような平たくて幅のあるパラレルケーブルが邪魔で悩むことはない。

IDEケーブルは幅があって色々と邪魔になることも多かったし、ケーブルの向きを変えるのも少々大変だった。シリアルATAのケーブルでは、そのような心配はない。

シリアルATA化によるもう1つの変化は、内蔵デバイスの電源コネクタシリアルATA用のものに切り替わったことだ。あれで、電源コネクタの挿抜が楽になった。以前の電源コネクタは、デバイスからなかなか抜けなくて難儀することが多かった気がする。

電源コネクタの着脱

電源コネクタのケーブル(電源と内蔵デバイスの間のケーブル)を着脱できる電源が増えた。必要なケーブルのみ取り付けることで、不要なケーブルに邪魔されてイライラすることが少なくなった。

シリアルATA化とあわせて、自作PCのケース内部の配線がスッキリするようになった要因だと思う。

SSDと2.5インチデバイス

小型PCならともかく、ミドルタワーやミニタワーPCに2.5インチデバイスを取り付けることは少なかったのだが……SSDがその流れを覆した。大抵のSSDは、大きくても2.5インチだ*2

古いミドルタワーPCには2.5インチデバイス用のベイが無いことも多い。リストアする際には変換マウンタのお世話になる。*3

まだ現時点では、大容量の記憶装置として3.5インチHDDは現役なのだが……通信回線がさらに高速化されてオンラインストレージへの移行が進むのか、それともSSDの単価が下がって置き換えられるのか、はたまた次世代記憶装置が登場するのか。少々興味深い。

オンラインストレージ通信回線というボトルネックを抱えているので、大量のデータを一度に操作したり、データのフルバックアップを実施したりする際に困る。SSDはまだ単価が高いし、「データ保存」という面で信用してよいものか悩ましい。次世代の記憶装置は、まだ決定的なものは無いようだ*4

まとめ(という名の感想)

古いミドルタワー/ミニタワーPCをリストアして中身を入れ替えると、ケーブル類が変わることで配線がスッキリする。あとMini-ITXマザーボードにすると、ケースとの対比で小ささにビックリする。内蔵型光学ドライブも無くなって、余計にスカスカに感じる。

デバイスと電源コネクタの挿抜は随分と楽になった。力の弱い方でも安心。

それと、地味に2.5インチデバイス用のベイや変換マウンタが欲しくなった。これからは、5インチ/3.5インチベイの組み合わせから、3.5インチ/2.5インチベイの組み合わせに移り変わっていくのだろうか?

*1:偏見かもしれないが。

*2:3.5インチのSSDも無くはないが、少々特殊だ。

*3:ちなみに、自宅のPCで変換マウンタのお世話になったことはない。15年ちょっと前のPCケースなのに、なぜか2.5インチHDDを取り付けるためのベイが用意されていた……。

*4:名前はチラホラと耳にするのだが。

2016-10-16

プログラミング言語の剰余演算子に惑う

いくつかのプログラミング言語を見ていると、算術演算子のうち四則演算の記号は、大抵の言語で同じだ。

演算記号
加算+
減算-
乗算*
除算/

上記の記号は、COBOLのCOMPUTE文でも通用する。

その一方、剰余演算子あたりから若干怪しくなってくる。私の普段使いの言語にて%が用いられていることが多いため、他の言語でも%が使えると思いこんでしまうことが多く、思わぬところでダメだしをくらう。

自分が今まで触れたことのある言語にて、%以外を用いていたものは、こんな感じだった。

言語剰余演算子
ActiveBasicMod
Clojuremodrem
COBOL(COMPUTE文)(なし)
Common Lispmodrem
Fortranmod関数
HSP\
OCamlmod
Prologmodrem
REXX//
Schememodmod0moduloremainder
Smalltalk\\rem:
VBScriptMod
Visual BasicMod

いくつかの言語では剰余(remainder)と法(modulo)が分かれているのが興味深い。

%の次に多いのがmodBASICFortranPascalPrologStandard MLなどで使われていた影響だろうか、modを使う言語は多い。その次に、いくつかの言語にてremが使われている。後は、REXXSmalltalkのように独自の記号を採用している言語もある。

四則演算以外の算術演算子で最もよく使うのが剰余演算子であるためか、%mod以外の言語に遭遇した時は、なぜだか妙に感動したものだ。

累乗(べき乗)あたりになってくると、そもそも言語によっては演算子を持たないこともあるので、言語による演算子の違いに驚くことはない。だが、剰余演算子は大抵の言語に用意されていて、使う機会も意外とあるように思う。つまり、割とメジャーな演算子だと思うのだが、四則演算ほどには演算子の記号が統一されていないように思う。

2016-10-07

「ANOMALY: use of REX.w is meaningless」問題の闇は深い

id:eel3:20160909:1473422844 に書いた、コマンドプロンプトで64bitビルドのコンソールアプリを使うと次のようにエラーメッセージが出力される問題:

[0x7FFFB4DF70E3] ANOMALY: use of REX.w is meaningless (default operand size is 64)

ひとまず、

――というところまで推測(というか妄想)している。

この問題、いやらしいことに、コンソールアプリスクリプトの利用に悪影響を及ぼしたり及ぼさなかったり、微妙に中途半端なのだ。

まあ、常に悪影響を及ぼすとなると、自分自身の作業上は大問題なのだが、そのような場合には私以外にも迷惑を被る人が多いだろうから、トレンドマイクロも対応せざるをえないはずだ。

しかし今回の場合、例えばコマンドプロンプト上でパイプやリダイレクトを使用したり(またはそのようなバッチファイルを実行したり)、PowerShell上で実行したり、Cygwinbash上で実行したりする分には、パイプやリダイレクトで得られる出力に余分なもの(=前述のエラーメッセージ)が紛れ込むことはない。コマンドプロンプトに毎度毎度エラーメッセージが表示されるのがうざいぐらいの被害で済む。

その一方で、Git for WindowsGit GUIや、CygwinRubyirbのように、エラーメッセージが悪影響を及ぼすケースもある。というか、Git GUIの場合、起動に失敗した際のエラーダイアログの中に件のエラーメッセージが紛れているので、どう考えてもエラーメッセージが悪さをしているとしか思えない。

つい最近分かったのだが、コマンドプロンプトからPowerShellスクリプトを実行して、標準出力の内容をパイプで受け取ったりファイルにリダイレクトしたりすると、エラーメッセージが紛れ込むようだ。

例えばこんなスクリプト

# hello.ps1
Set-StrictMode -Version Latest

"hello, world"

これをPowerShellから実行する分には問題ない。

PS C:\Users\fabrico> .\hello.ps1
hello, world
PS C:\Users\fabrico> .\hello.ps1 > out.txt
PS C:\Users\fabrico> Get-Content .\out.txt
hello, world
PS C:\Users\fabrico> _

しかし、コマンドプロンプトから実行すると:

C:\Users\fabrico>powershell -ExecutionPolicy RemoteSigned -File hello.ps1
[0x7FFB9EAB70E3] ANOMALY: use of REX.w is meaningless (default operand size is 64)
hello, world

C:\Users\fabrico>powershell -ExecutionPolicy RemoteSigned -File hello.ps1 > out.txt

C:\Users\fabrico>type out.txt
hello, world
[0x7FFB9EAB70E3] ANOMALY: use of REX.w is meaningless (default operand size is 64)

C:\Users\fabrico>powershell -Command "\"hello, world\""
[0x7FFB9EAB70E3] ANOMALY: use of REX.w is meaningless (default operand size is 64)
hello, world

C:\Users\fabrico>powershell -Command "\"hello, world\"" > out2.txt
[0x7FFB9EAB70E3] ANOMALY: use of REX.w is meaningless (default operand size is 64)

C:\Users\fabrico>type out2.txt
hello, world
[0x7FFB9EAB70E3] ANOMALY: use of REX.w is meaningless (default operand size is 64)

C:\Users\fabrico> _

リダイレクトした出力先ファイルにエラーメッセージが混入している(typeはcmd.exeの組み込みコマンドなので、実行時にエラーメッセージは表示されない点に注意)。パイプ経由でclipに送り込んだ場合も同じだ。

ところで、前述したように、普通にコマンドプロンプト上でコンソールアプリを実行して出力をパイプやリダイレクトに流し込んだ場合は、その出力にエラーメッセージは混入しない。

つまり、コンソールアプリスクリプトを実行する際の、標準出力のハンドリング方法か何かが最低でも2種類存在して、そのどちらを使っているかによって、悪影響を受けるか否かが分かれることになる――という風に推測できる。

こうなると、デバッグ(というか問題の影響範囲の調査)は大変になるし、迷惑を被る人が少なくなるからトレンドマイクロの対応も微妙になりかねない。

正直なところ、なぜコマンドプロンプトからPowerShellスクリプトを実行した場合にだけ問題となるのか、いまいち納得できない。本当に、何で?

追記:2016-10-15

何種類かのOSで実験してみた。

OSウイルスバスター問題発生の有無
Windows 7 64bitウイルスバスタークラウド11問題なし
Windows 10 Home Ver.1511 64bitウイルスバスタークラウド11問題なし
Windows 10 Home Ver.1607 64bitウイルスバスタークラウド11問題あり

Windows 10でもVer.1511までは問題なし。しかしVer.1607(Anniversary Update)を適用したり、もしくは最初からVer.1607でクリーンインストールしたりすると、この問題が発生するようになる。

実は「Windows 10 Ver.1607 + ウイルスバスタークラウド10」の組み合わせも検証したかったのだが、トレンドマイクロダウンロードサイトから落としたファイル(TTi_10.0_HE_64bit.exe)を使っても、ウイルスバスタークラウド10の頃の体験版インストーラ(TrendMicro-TTi_10.0_HE_Downloader.exe)を使っても、最終的にウイルスバスタークラウド11がインストールされてしまうため、検証しようにも無理だった。

――ということは、ウイルスバスタークラウドの旧バージョンで急場をしのぐことが不可能なのか。支障が出るツールを検証して個別対応するか、他のアンチウイルスソフトを試してみるか……うーん、悩ましい。

追記:2016-11-05

以下のケースでも実害が発生することを確認した。

  • Qtのwindeployqt.exe。
    • QMLを併用しているプロジェクトにて、windeployqt.exeが内部で呼び出しているqmlimportscanner.exeの出力(JSON)に件のエラーメッセージが混入してしまい、誤ったフォーマットになってしまうことで、処理が中断されてしまう。
  • Windows Script Hostのcscriptによるスクリプト

windeployqt.exeのケースは、Git for WindowsGit GUIのケースと同様に、サードパーティのツールの動作に悪影響が出ている一例だ。

cscriptのケースは、PowerShellのケースのように、どちらかと言えば自作スクリプトに悪影響が及ぶ一例だが、PowerShellとは違って回避策が無いのが問題だ。

うーん、早くパッチが出てくれないだろうか。