Linux/雑記
目次
覚え書き
未分類の覚え書き。
cpio コマンド
よく忘れるのでメモ。man も見にくいし。
- -i — ファイル抽出
- -d — 必要に応じてディレクトリを作成
- -m — ファイルの更新時刻を保持
- -t — リスト表示
- -v — verbose
$ rpm2cpio hoge.rpm | cpio -ivdm # 全ファイル抽出 $ rpm2cpio hoge.rpm | cpio -tv # リスト表示 (ls -l)
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
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() で使われるバッファを経由しないから、順番が入れ替わっちゃうわけね。おもろい。