「Linux/雑記」の版間の差分
(→覚え書き) |
(→覚え書き) |
||
(同じ利用者による、間の13版が非表示) | |||
行1: | 行1: | ||
== 覚え書き == | == 覚え書き == | ||
未分類の覚え書き。 | 未分類の覚え書き。 | ||
+ | |||
+ | === dd コマンドについて === | ||
+ | ==== ピンポイント書き込み ==== | ||
+ | |||
+ | 例えば、64 バイトのデータの 31-32 バイト目だけを書き換えたい場合。 | ||
+ | |||
+ | # od -Ad -tx1 test -v | ||
+ | 0000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ||
+ | 0000016 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ||
+ | 0000032 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ||
+ | 0000048 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ||
+ | 0000064 | ||
+ | # echo -n $'\x55'$'\xaa' | dd of=test bs=1 seek=30 conv=notrunc | ||
+ | 2+0 records in | ||
+ | 2+0 records out | ||
+ | 2 bytes (2 B) copied, 3.7856e-05 seconds, 52.8 kB/s | ||
+ | # od -Ad -tx1 test -v | ||
+ | 0000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ||
+ | 0000016 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa | ||
+ | 0000032 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ||
+ | 0000048 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ||
+ | 0000064 | ||
+ | |||
+ | <code>conv=notrunc</code> がないと、書き込みが終わった位置で切り詰められてしまうので要注意。 | ||
+ | |||
+ | === man コマンドについて === | ||
+ | ==== 整形幅を指定する ==== | ||
+ | デフォルトでは、ターミナルの幅に整形されてしまうので、横長いターミナルを利用している場合、コピーしてメールなどにそのまま貼り付けるのには適さない。以下の環境変数で、整形幅を指定することができる。 | ||
+ | $ MANWIDTH=80 man ... | ||
+ | |||
+ | === cpio コマンドについて === | ||
+ | よく忘れるのでメモ。man も見にくいし。 | ||
+ | * -i — ファイル抽出 | ||
+ | ** -d — 必要に応じてディレクトリを作成 | ||
+ | ** -m — ファイルの更新時刻を保持 | ||
+ | * -t — リスト表示 | ||
+ | * -v — verbose | ||
+ | $ rpm2cpio hoge.rpm | cpio -ivdm # 全ファイル抽出 | ||
+ | $ rpm2cpio hoge.rpm | cpio -tv # リスト表示 (ls -l) | ||
+ | |||
+ | === Makefile について === | ||
+ | * http://www.unixuser.org/~euske/doc/makefile/ | ||
+ | * コマンドの前に '-' をつけると、エラーが発生しても make を続ける | ||
+ | * コマンドの前に '@' をつけると、コマンドを標準出力に表示しない | ||
+ | |||
+ | === initrd を展開する === | ||
+ | initrd (イニシャル RAM ディスク) は gzip で圧縮されているようである。 | ||
+ | |||
+ | [root@centos52 ~]# file /boot/initrd-2.6.18-164.11.1.el5.img | ||
+ | /boot/initrd-2.6.18-164.11.1.el5.img: gzip compressed data, from Unix, last modified: Sat Mar 13 13:07:34 2010, max compression | ||
+ | |||
+ | 解凍してみると、今度は cpio アーカイブだということがわかる。 | ||
+ | |||
+ | [root@centos52 ~]# gzip -cd /boot/initrd-2.6.18-164.11.1.el5.img > initrd | ||
+ | [root@centos52 ~]# file initrd | ||
+ | initrd: ASCII cpio archive (SVR4 with no CRC) | ||
+ | |||
+ | ということで、こんな感じで展開できる。 | ||
+ | |||
+ | [root@centos52 ~]# mkdir tmp && cd tmp | ||
+ | [root@centos52 tmp]# gzip -cd /boot/initrd-2.6.18-164.11.1.el5.img | cpio -idvm | ||
+ | |||
+ | ちなみに、cpio のオプションって面白くて、人によって様々なうえ、同じ人が実行する時は必ず同じオプションなので | ||
+ | /root/.bash_history などを見ると誰が実行したのかがわかる。オレが cpio で展開するするときはいつも -idvm を付けるし、 | ||
+ | こないだ上司が打っているのを見ていたら、-B とか -u とかも入っていたように見えた。 | ||
+ | |||
+ | オプションが複雑だから半分おまじないとして覚えてしまうんだよな。それぞれの意味は忘れちゃってる。 | ||
+ | |||
+ | === crash の使い方 === | ||
+ | 情けないことだが、ダンプファイルの開き方自体を毎回忘れてしまう。 | ||
+ | man crash を見てもパッと見ではわからないのでメモしておく。 | ||
+ | |||
+ | # crash /boot/System.map-XXX /usr/lib/debug/lib/modules/XXX/vmlinux vmcore | ||
+ | ※XXX は該当するカーネルバージョン | ||
+ | |||
+ | === 万能ビューア less === | ||
+ | ここ 2, 3 年はほぼ毎日 Linux 触ってるのに知らなかった驚愕の事実。 | ||
+ | |||
+ | 例えば、gzip 圧縮されたファイルがあるとする。 | ||
+ | $ echo hoge | gzip -cf > hoge.gz # "hoge" という文字列を圧縮したものを hoge.gz として保存 | ||
+ | $ zcat hoge.gz # ふつう、テキストなら zcat とかで内容を確認できる。 | ||
+ | hoge | ||
+ | 実は、less でもそのまま閲覧可能だ。 | ||
+ | $ less hoge.gz | ||
+ | hoge | ||
+ | これは、シェルスクリプト /usr/bin/lesspipe.sh にて実装されている機能である。 | ||
+ | スクリプトを確認すると、gz ファイルの他にも、主に以下のものを表示可能だ。 | ||
+ | * man ページ (圧縮されたものを含む) | ||
+ | * tar ファイル (内容リスト表示; gzip, bzip2 圧縮されたものを含む) | ||
+ | * zip ファイル (内容リスト表示) | ||
+ | * rpm パッケージ (パッケージ情報、更新履歴、内容リスト表示) | ||
+ | * cpio ファイル (内容リスト表示) | ||
+ | * 各種画像ファイル (画像情報表示) | ||
+ | 使用するスクリプトは環境変数 LESSOPEN で指定可能なので、 | ||
+ | 自分仕様に less をカスタマイズすることもできる。 | ||
+ | [hagio@lab ~]$ echo $LESSOPEN | ||
+ | |/usr/bin/lesspipe.sh %s | ||
=== /proc/diskstats の各項目の意味 === | === /proc/diskstats の各項目の意味 === | ||
行44: | 行141: | ||
last update of this field. This can provide an easy measure of both | last update of this field. This can provide an easy measure of both | ||
I/O completion time and the backlog that may be accumulating. | I/O completion time and the backlog that may be accumulating. | ||
− | + | ★I/O 数 x 経過時間 = I/O のべ時間 | |
+ | (個々の I/O の待ち時間を含む開始から完了までの時間の総和) | ||
=== tar で必要なファイルのみを抽出 === | === tar で必要なファイルのみを抽出 === | ||
行76: | 行174: | ||
=== date コマンドについて === | === date コマンドについて === | ||
+ | |||
+ | ==== 時間を進める/戻す ==== | ||
しょーもないけど覚え書き。ntp の実験なんかで時刻を書き換えたい場合、 | しょーもないけど覚え書き。ntp の実験なんかで時刻を書き換えたい場合、 | ||
# date --set "10 seconds ago" | # date --set "10 seconds ago" | ||
行85: | 行185: | ||
ちなみに、hwclock コマンドも同様のフォーマットが利用可能だ。 | ちなみに、hwclock コマンドも同様のフォーマットが利用可能だ。 | ||
# hwclock --set --date "10 sec ago" | # hwclock --set --date "10 sec ago" | ||
+ | |||
+ | ==== UNIX 時間を可読化 ==== | ||
+ | わざわざ awk を使って、以下のようにやっていたが、 | ||
+ | $ echo 1260750958 | awk '{print strftime("%F %T", $0)}' | ||
+ | 2009-12-14 09:35:58 | ||
+ | date コマンドでも可能だった!! | ||
+ | $ date -d @1260750958 | ||
+ | 2009年 12月 14日 月曜日 09:35:58 JST | ||
+ | |||
+ | ==== 可読時間を UNIX 時間化 ==== | ||
+ | 逆変換も可能!! | ||
+ | # date +%s ★現在 | ||
+ | 1284543415 | ||
+ | # date +%s -d 'Sep 15 18:37:10' ★messages 形式 (今年になる) | ||
+ | 1284543430 | ||
+ | # date +%s -d 'Sep 15 18:37:10 2009' ★messages 形式 (西暦指定) | ||
+ | 1253007430 | ||
+ | # date +%s -d '2010/09/15 18:37:10' ★日本的形式 | ||
+ | 1284543430 | ||
=== top について === | === top について === | ||
行116: | 行235: | ||
ホスト名 "server" だけではダメで、FQDN にしたら接続できた。要するに、hostname コマンドの出力結果を貼付ける。 | ホスト名 "server" だけではダメで、FQDN にしたら接続できた。要するに、hostname コマンドの出力結果を貼付ける。 | ||
これも数時間ハマった。なぜこうしないといけないのかは不明なので、そのうち調査する。 | これも数時間ハマった。なぜこうしないといけないのかは不明なので、そのうち調査する。 | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
=== <code>ioctl()</code> の使い方 === | === <code>ioctl()</code> の使い方 === |
2011年6月22日 (水) 01:15時点における最新版
目次
- 1 覚え書き
- 1.1 dd コマンドについて
- 1.2 man コマンドについて
- 1.3 cpio コマンドについて
- 1.4 Makefile について
- 1.5 initrd を展開する
- 1.6 crash の使い方
- 1.7 万能ビューア less
- 1.8 /proc/diskstats の各項目の意味
- 1.9 tar で必要なファイルのみを抽出
- 1.10 locate 用データベースから除外
- 1.11 ビープ音がうるさい
- 1.12 date コマンドについて
- 1.13 top について
- 1.14 telnet-server について
- 1.15 ioctl() の使い方
- 1.16 /etc/sysconfig/i18n について
- 2 その他
覚え書き
未分類の覚え書き。
dd コマンドについて
ピンポイント書き込み
例えば、64 バイトのデータの 31-32 バイト目だけを書き換えたい場合。
# od -Ad -tx1 test -v 0000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0000016 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0000032 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0000048 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0000064 # echo -n $'\x55'$'\xaa' | dd of=test bs=1 seek=30 conv=notrunc 2+0 records in 2+0 records out 2 bytes (2 B) copied, 3.7856e-05 seconds, 52.8 kB/s # od -Ad -tx1 test -v 0000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0000016 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa 0000032 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0000048 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0000064
conv=notrunc
がないと、書き込みが終わった位置で切り詰められてしまうので要注意。
man コマンドについて
整形幅を指定する
デフォルトでは、ターミナルの幅に整形されてしまうので、横長いターミナルを利用している場合、コピーしてメールなどにそのまま貼り付けるのには適さない。以下の環境変数で、整形幅を指定することができる。
$ MANWIDTH=80 man ...
cpio コマンドについて
よく忘れるのでメモ。man も見にくいし。
- -i — ファイル抽出
- -d — 必要に応じてディレクトリを作成
- -m — ファイルの更新時刻を保持
- -t — リスト表示
- -v — verbose
$ rpm2cpio hoge.rpm | cpio -ivdm # 全ファイル抽出 $ rpm2cpio hoge.rpm | cpio -tv # リスト表示 (ls -l)
Makefile について
- http://www.unixuser.org/~euske/doc/makefile/
- コマンドの前に '-' をつけると、エラーが発生しても make を続ける
- コマンドの前に '@' をつけると、コマンドを標準出力に表示しない
initrd を展開する
initrd (イニシャル RAM ディスク) は gzip で圧縮されているようである。
[root@centos52 ~]# file /boot/initrd-2.6.18-164.11.1.el5.img /boot/initrd-2.6.18-164.11.1.el5.img: gzip compressed data, from Unix, last modified: Sat Mar 13 13:07:34 2010, max compression
解凍してみると、今度は cpio アーカイブだということがわかる。
[root@centos52 ~]# gzip -cd /boot/initrd-2.6.18-164.11.1.el5.img > initrd [root@centos52 ~]# file initrd initrd: ASCII cpio archive (SVR4 with no CRC)
ということで、こんな感じで展開できる。
[root@centos52 ~]# mkdir tmp && cd tmp [root@centos52 tmp]# gzip -cd /boot/initrd-2.6.18-164.11.1.el5.img | cpio -idvm
ちなみに、cpio のオプションって面白くて、人によって様々なうえ、同じ人が実行する時は必ず同じオプションなので /root/.bash_history などを見ると誰が実行したのかがわかる。オレが cpio で展開するするときはいつも -idvm を付けるし、 こないだ上司が打っているのを見ていたら、-B とか -u とかも入っていたように見えた。
オプションが複雑だから半分おまじないとして覚えてしまうんだよな。それぞれの意味は忘れちゃってる。
crash の使い方
情けないことだが、ダンプファイルの開き方自体を毎回忘れてしまう。 man crash を見てもパッと見ではわからないのでメモしておく。
# crash /boot/System.map-XXX /usr/lib/debug/lib/modules/XXX/vmlinux vmcore ※XXX は該当するカーネルバージョン
万能ビューア less
ここ 2, 3 年はほぼ毎日 Linux 触ってるのに知らなかった驚愕の事実。
例えば、gzip 圧縮されたファイルがあるとする。
$ echo hoge | gzip -cf > hoge.gz # "hoge" という文字列を圧縮したものを hoge.gz として保存 $ zcat hoge.gz # ふつう、テキストなら zcat とかで内容を確認できる。 hoge
実は、less でもそのまま閲覧可能だ。
$ less hoge.gz hoge
これは、シェルスクリプト /usr/bin/lesspipe.sh にて実装されている機能である。 スクリプトを確認すると、gz ファイルの他にも、主に以下のものを表示可能だ。
- man ページ (圧縮されたものを含む)
- tar ファイル (内容リスト表示; gzip, bzip2 圧縮されたものを含む)
- zip ファイル (内容リスト表示)
- rpm パッケージ (パッケージ情報、更新履歴、内容リスト表示)
- cpio ファイル (内容リスト表示)
- 各種画像ファイル (画像情報表示)
使用するスクリプトは環境変数 LESSOPEN で指定可能なので、 自分仕様に less をカスタマイズすることもできる。
[hagio@lab ~]$ echo $LESSOPEN |/usr/bin/lesspipe.sh %s
/proc/diskstats の各項目の意味
Documentation/iostats.txt に書いてあった。
Field 1 -- # of reads completed This is the total number of reads completed successfully. ★読み込みが成功した回数 Field 2 -- # of reads merged, field 6 -- # of writes merged Reads and writes which are adjacent to each other may be merged for efficiency. Thus two 4K reads may become one 8K read before it is ultimately handed to the disk, and so it will be counted (and queued) as only one I/O. This field lets you know how often this was done. ★読み書きの I/O がそれぞれまとめて行なわれた回数 Field 3 -- # of sectors read This is the total number of sectors read successfully. ★読み込みに成功したセクタ数 Field 4 -- # of milliseconds spent reading This is the total number of milliseconds spent by all reads (as measured from __make_request() to end_that_request_last()). ★読み込みにかかった時間 (ミリ秒) Field 5 -- # of writes completed This is the total number of writes completed successfully. ★書き込みが成功した回数 Field 7 -- # of sectors written This is the total number of sectors written successfully. ★書き込みに成功したセクタ数 Field 8 -- # of milliseconds spent writing This is the total number of milliseconds spent by all writes (as measured from __make_request() to end_that_request_last()). ★書き込みにかかった時間 (ミリ秒) Field 9 -- # of I/Os currently in progress The only field that should go to zero. Incremented as requests are given to appropriate request_queue_t and decremented as they finish. ★実行中の I/O リクエスト数 Field 10 -- # of milliseconds spent doing I/Os This field is increases so long as field 9 is nonzero. ★I/O リクエストが存在した時間?(ミリ秒) Field 11 -- weighted # of milliseconds spent doing I/Os This field is incremented at each I/O start, I/O completion, I/O merge, or read of these stats by the number of I/Os in progress (field 9) times the number of milliseconds spent doing I/O since the last update of this field. This can provide an easy measure of both I/O completion time and the backlog that may be accumulating. ★I/O 数 x 経過時間 = I/O のべ時間 (個々の I/O の待ち時間を含む開始から完了までの時間の総和)
tar で必要なファイルのみを抽出
以下のようなファイルがあるとして、hoge だけを抽出したければ
[hagio@localhost ~]$ tar tzf test.tar.gz dir1/ dir1/hoge dir1/fuga dir2/ dir2/fuga [hagio@localhost ~]$ tar xzf test.tar.gz *hoge [hagio@localhost ~]$ ls dir1 test.tar.gz
locate 用データベースから除外
locate でファイルを検索する際、updatedb にて作成されたデータベースが用いられる。 テンポラリファイルや、バックアップファイルなどを検索する必要はないので、 これらを除外しておけば無駄がなくなると思われる。
# vi /etc/updatedb.conf PRUNEFS = "auto afs iso9660 sfs udf" ★PRUNEPATHS = "/afs /media /net /sfs /tmp /udev /var/spool/cups /var/spool/squid /var/tmp"
ここに除外するディレクトリを追加すれば良い。
ビープ音がうるさい
# vi /etc/inputrc set bell-style none
date コマンドについて
時間を進める/戻す
しょーもないけど覚え書き。ntp の実験なんかで時刻を書き換えたい場合、
# date --set "10 seconds ago"
といった書き方ができる。時刻を進めるには、ago の反対が必要… かと思っていろいろ調べていたが見つからない。
# date --set "10 seconds"
で 10 秒後に進められるじゃん orz
ちなみに、hwclock コマンドも同様のフォーマットが利用可能だ。
# hwclock --set --date "10 sec ago"
UNIX 時間を可読化
わざわざ awk を使って、以下のようにやっていたが、
$ echo 1260750958 | awk '{print strftime("%F %T", $0)}' 2009-12-14 09:35:58
date コマンドでも可能だった!!
$ date -d @1260750958 2009年 12月 14日 月曜日 09:35:58 JST
可読時間を UNIX 時間化
逆変換も可能!!
# date +%s ★現在 1284543415 # date +%s -d 'Sep 15 18:37:10' ★messages 形式 (今年になる) 1284543430 # date +%s -d 'Sep 15 18:37:10 2009' ★messages 形式 (西暦指定) 1253007430 # date +%s -d '2010/09/15 18:37:10' ★日本的形式 1284543430
top について
top の man ページは読みづらいので、あまり読みたくない。
すべてのプロセスの top 情報を表示する
通常は画面に収まるだけのプロセスの情報しか表示されないが、すべてを出力することもできる。
# top -bn 1
-
-b
- バッチモード。テキストに出力する場合はこれを使う。
-
-n number
- 出力する回数を指定する。
激速 top
# top -d 0.01
-
-d ss.tt
- 出力する間隔を指定する。マニュアルには、小数点以下は 1/10 秒と書いてあるが、1/100 秒までいけるようだ。よって、0.01 が最速で、Celeron 1.80 GHz だと 40 % 程度の CPU 時間を消費する。かるーく負荷をかけたいときなんかには、調節ができて便利。(ぇ
telnet-server について
telnet サーバの立ち上げかたと、ハマったところ。
-
/etc/xinetd.d/telnet
中のdisable = yes
をno
にする-
chkconfig telnet on
でもよい
-
-
/etc/init.d/xinetd restart
で xinetd を再起動する (これがわからずハマった…)
以下のようなエラーが出て接続できない場合
Trying 192.168.1.1... Connected to server. Escape character is '^]'. getaddrinfo: localhost Name or service not known Connection closed by foreign host.
/etc/hosts に 192.168.1.1 server.hagio.org
を追加するとよい。
ホスト名 "server" だけではダメで、FQDN にしたら接続できた。要するに、hostname コマンドの出力結果を貼付ける。
これも数時間ハマった。なぜこうしないといけないのかは不明なので、そのうち調査する。
ioctl()
の使い方
- 基本的には、
fd = open()
してioctl(fd, request, ...)
してclose(fd)
という流れ。 -
request
は、man ioctl_list
から探す。引き数の型も書いてあるので、これを参考にする。 - サンプルコード:setro.c - RO (リードオンリー) フラグをセットする
#include <stdio.h> #include <fcntl.h> #include <linux/fs.h> int main(int argc, char* argv[]) { int fd, res, flag; if (argc != 3) { printf("Usage: setro DEVICE RO_FLAG\n"); return 1; } if ((fd = open(argv[1], O_RDWR)) < 0) { perror("open() failed"); return 1; } flag = (int) *argv[2] - '0'; if ((res = ioctl(fd, BLKROSET, &flag)) < 0) { perror("ioctl() failed"); close(fd); return 1; } close(fd); return 0; }
実行例:/dev/sda1 (/boot) をリードオンリーにする。
[root@centos52 ~]# umount /boot ★いったんアンマウント [root@centos52 ~]# ./setro /dev/sda1 1 ★リードオンリーにセット [root@centos52 ~]# mount /boot mount: ブロックデバイス /dev/sda1 は書き込み禁止です、読込み専用でマウントします [root@centos52 ~]# umount /boot [root@centos52 ~]# ./setro /dev/sda1 0 ★リードオンリーを解除 [root@centos52 ~]# mount /boot
/etc/sysconfig/i18n
について
- 読み込まれる場所
-
/etc/rc.d/rc.sysinit
(rhgb 利用時のみ?) -
/etc/init.d/functions
→/etc/profile.d/lang.sh
-
/etc/init.d/firstboot
-
-
SUPPORTED
はsystem-config-language
(GUI アプリ) が使う
その他
リダイレクトの謎
リダイレクトの動きを確認するために、標準出力と標準エラーに文字列を吐くプログラムを書いた。
[hagio@lab ~]$ cat > stdout.c #include <stdio.h> int main(void) { fprintf(stdout, "stdout\n"); fprintf(stderr, "stderr\n"); return 0; }
これを普通に実行すると、もちろん stdout が先に出力される。
[hagio@lab ~]$ cc -o stdout stdout.c && ./stdout stdout stderr
しかし、標準出力と標準エラーを同じファイルにリダイレクトすると…
[hagio@lab ~]$ ./stdout > test 2>&1 [hagio@lab ~]$ cat test stderr stdout
なぜ逆転する?? とりあえず、ltrace を取ってみる。
[hagio@lab ~]$ ltrace -tt -o ltrace.log ./stdout > tmp 2>&1 [hagio@lab ~]$ cat tmp stderr stdout [hagio@lab ~]$ cat ltrace.log 20:03:34.192236 __libc_start_main(0x80483d4, 1, 0xbf80f644, 0x8048450, 0x8048440 <unfinished ...> 20:03:34.192460 fwrite("stdout\n", 1, 7, 0x5de4c0) = 7 20:03:34.193010 fwrite("stderr\n", 1, 7, 0x5de560) = 7 20:03:34.193327 +++ exited (status 0) +++
ちゃんと "stdout" を書き出す方が先に呼び出されている。しかし、strace を取ってみると…
[hagio@lab ~]$ strace -tt -o strace.log ./stdout > tmp 2>&1 [hagio@lab ~]$ tail -n 4 strace.log 20:05:49.658550 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f62000 20:05:49.658611 write(2, "stderr\n", 7) = 7 20:05:49.658907 write(1, "stdout\n", 7) = 7 20:05:49.658993 exit_group(0) = ?
うむむむむ、これは何か「エラーは早く表示すべき」みたいなバイアスがかかってるのか…。 glibc が怪しいので、ソースでも見てみるか。
2009/06/30 少し追ってみたが、glibc 全然読めん…。ただ、気になったのはここ
"libio/stdfiles.c" DEF_STDFILE(_IO_2_1_stdin_, 0, 0, _IO_NO_WRITES); DEF_STDFILE(_IO_2_1_stdout_, 1, &_IO_2_1_stdin_, _IO_NO_READS); DEF_STDFILE(_IO_2_1_stderr_, 2, &_IO_2_1_stdout_, _IO_NO_READS+_IO_UNBUFFERED);★
_IO_UNBUFFERED というフラグが立っているようだ。 なるほど、通常 fwrite() で使われるバッファを経由しないから、順番が入れ替わっちゃうわけね。おもろい。