kSar(http://ksar.atomique.net/) が便利。
sar のテキスト出力を GUI インターフェイスでレポート形式に変換し、PDF や画像ファイルで保存できます。
– sysstat で性能管理
– kSar 公式(English)
– kSarでsarデータをグラフにする
– kSarによるsarのグラフ化について
タグ: Linux
Linuxで間違って削除したファイルを復元する
Sleuth kit というフォレンジックツールを使うとよさそうです。Autopsy という別ツールを組み合わせれば web ベース GUI が利用できます。
対象ファイルシステムは: NTFS, FAT, UFS1, UFS2, EXT2FS, EXT3FS, ISO9660 です。
Windows 系ファイルシステムや CD などメディアのデータ復旧にも使えるのがいいですね。
なお, FreeBSD ports は sysutils/sleuthkit, sysutils/autopsy にあります。
参考:
http://www.gentoo.org/news/ja/gmn/20080728-newsletter.xml
tput – 端末入力で遊ぶ
wget のプログレスバーや, lynx, w3m などの CUI ブラウザ、NetHack などの CUI ゲームなどのように、CUI 画面内の一部だけを動的に書き換える、という処理を実装する方法をメモしておきます。
基本として、CUI の描画方法を制御するには特定のキーコードに割り当てられている画面描画の処理命令を利用します。
標準出力に出力された時点で命令が実行されるので、制御コードを知ってさえいれば echo だけで画面描画が実現できてしまいます。次のように入力すると画面をクリアします。
$ echo \
capname については man terminfo の Cap-Name を参照。
例:
% zmodload zsh/terminfo
% echoti setaf 2
% echo Hello,world
Hello,world
参考: http://d.hatena.ne.jp/lurker/20061121
・tput
zsh 以外のシェルからでも使える汎用プログラム。Curses や NCurses に含まれています。なお、FreeBSD に最初から含まれている /usr/bin/tput は Curses 版です。
Curses 版の書式 (FreeBSDなど):
$ tput <TCapCode> [ 引数… ]
TCapCode については man termcap の TCapCode を参照。
NCurses 版の書式 (FreeBSD ports や Linux など):
$ tput <CapName>
CapName については man terminfo の Cap-Name を参照。
curses よりこちらのほうが一般的です。
curses tput の例:
15 行 20 文字目に文字列 OK を書き込む。
$ tput sc; tput cm 20 15; tput al;echo OK; tput rc
文字に下線を入れる
$ tput us ; echo hello; tput ue
Ncurses tput の例:
文字の色を赤に。
$ tput setaf 1
白に戻す。
$ tput setaf 9
参考: http://www.ibm.com/developerworks/jp/linux/aix/library/au-learningtput/index.html
複数ファイルの中身を一括置換するには
複数のファイルをまとめて置き換えたいときは sed を使うと便利です。
たとえばこのようにすると指定したディレクトリの中のすべての .html ファイルの内容を 2007年 から 2008 年に書き換えることができます。
for i in `find /var/www/html -type f -iregex ‘.*\.html’`; do
mv $i $i.bak
sed -e ‘s/2007年/2008年/g’ $i.bak > $i
done
影響があったファイルの一覧を得るには次のようにします
for i in `find /var/www/html -type f -iregex ‘.*\.html’`; do
diff -q $i.bak $i
done
影響があったファイルの内容を比較する場合も diff を使います。
for i in `find /var/www/html -type f -iregex ‘.*\.html’`; do
echo $i
diff $i.bak $i
done
問題に気づいて元に戻したいときは *.bak を移動させれば元に戻ります。
for i in `find /var/www/html -type f -iregex ‘.*\.html’`; do
mv $i.bak $i
done
変更が問題なければ .bak ファイルを削除して置換完了です。
for i in `find /var/www/html -type f -iregex ‘.*\.html’`; do
rm $i.bak
done
参考:
sed の使い方
sed の使い方
書式:
sed -e ‘コマンド1’ [-e ‘コマンド2’ […]] [‘ファイル名’]
指定したファイル(省略した場合は標準入力)を入力テキストとして読み込み、
-e で指定したスクリプトを順番に実行して標準出力に書き出します。
-e で指定できる書式は次のようなものがあります。
■命令のみ指定するタイプ( -e 命令 ):
-e p
行バッファの内容を出力(Print)する。バッファの内容は操作しないため、-ep -ep のように複数指定すると指定回出力されます。バッファの消去には後述の d を使用します。また、全てのスクリプトを実行したあとにもバッファ内容が出力されます。
-e d
行バッファの内容を消去(Delete)する。通常、p 命令と組み合わせて利用します。
■正規表現パターン + 処理内容指定をするタイプ(-e /正規表現/命令):
-e /^foo/p
foo から始まる行を出力します。
-e ‘/boO$/d’
boO で終わる行をバッファから削除します。
-e ‘/[J][j]ohn/p’
John または john が含まれる行を出力します。
■正規表現による置換(-e s/正規表現/置換内容/オプション)
-e s/foo/boo/
各行バッファで最初に見つかった foo を boo に置換します。
-e ‘s/a/A/g’
バッファ中の全ての a を A に置換します。
-e s/john/JOHN/ig
バッファ中の全ての john(大文字小文字問わない)を大文字の JOHN に統一します。
例:
echo “Hallo, world” | sed -e s/a/e/
typo を訂正する(Hallo -> Hello)。
cat /var/log/httpd/access_log | sed -e ‘/GET/p’ -e ‘/^127\.0\.0\.1/p’ -ed
Apache のローカルからの GET アクセスを抽出する。
作業中のプロセスを残したまま端末を終了する
何かをビルドしていて、時間が予想外にかかってしまい、nohup もしていないためになかなか端末を閉じることができずに予定が狂って結局残業時間がのびる、なんてことありませんか?
そういうときは disown を使うと実行中のジョブを端末から切り離すことができます。
(以下は bash の例です)
$ make # 何か時間のかかる作業
## 出力は略。途中で端末接続を切りたくなった(Ctrl-Z) ##
^Z
[1]+ Stopped make
$ bg # バックグラウンドで実行を再開
## 略。出力再開 ##
$ disown # 端末を切ってもプロセスが残るようにカレントジョブ( %1 )を端末から切り離す
$ exit # 終了
nohup と違い端末を切ると標準出力、エラー出力はどこにも出力されなくなりますが、これで端末を切断してもプロセスが実行されたままになります。
参考:
一度 tty から起動したプロセス(PBD)
一度 tty から起動したプロセス (csh/ksh 版)(にぽたん研究所)
tips – ltrace で共有ライブラリの関数呼び出しをトレースする
http://0xcc.net/blog/archives/000103.html
より。
ltrace [ {オプション} ] {実行するプログラム} [ {引数..} ]
のようにすると、任意のプログラムを動的にブレークポイントを挿入して実行し、共有ライブラリとシステムコールの呼び出しをトレースすることができます。
簡単にいうと GDB より高級なデバッガのような感じです。
Linux の場合は標準でインストールされることが多そうですが、yum や apt-get を使う場合は
yum install ltrace
または
apt-get install ltrace
でインストールできます。
また FreeBSD の場合も ports に含まれているため、
portinstall sysutils/ltrace
とすることでインストールできます。
利用例:
ls / を実行しライブラリ関数をトレースし、log.txt にトレース結果を出力する(-o)。
$ ltrace -o log.txt ls / # プログラムの実行とトレース
bin dev home lib media mnt proc sbin tmp var
boot etc initrd lost+found misc opt root sys usr
$ cat log.txt # トレース結果参照
_start(0xbff1abd4, 0xbff1abd7, 0, 0xbff1abd9, 0xbff1abf0 <unfinished …>
__libc_start_main(0x804ea41, 2, 0xbfe34df4, 0x8056f58, 0x8056fac <unfinished …
setlocale(6, “”) = “en_US”
bindtextdomain(“coreutils”, “/usr/share/locale”) = “/usr/share/locale”
textdomain(“coreutils”) = “coreutils”
__cxa_atexit(0x8053701, 0, 0, 0x805b570, 0xbfe34d68) = 0
is_selinux_enabled(0x8053701, 0xd1bbe4, 0x32206e75, 0x34312036, 0x3a30333a) = 0
isatty(1) = 1
# 以下略
利用例2:
ライブラリのトレースだけでなくシステムコールもトレース(-S)し、
関数呼び出しの関係を階層構造で出力する(-n {number})。
$ ltrace -o log2.txt -S -n 2 ls /
# 略$ cat log2.txt
SYS_uname(0xbfe4106c) = 0SYS_brk(NULL) = 0x99ca000
SYS_access(0xbffdc1, 4, 0xc03fd4, 0xbffdc1, 4) = -2
SYS_open(“/etc/ld.so.cache”, 0, 00) = 3
# 中略
SYS_munmap(0xb7f92000, 4096) = 0
_start(0xbff20bd4, 0xbff20bd7, 0, 0xbff20bd9, 0xbff20bf0 <unfinished …>
__libc_start_main(0x804ea41, 2, 0xbfe412c4, 0x8056f58, 0x8056fac <unfinished
…>
setlocale(6, “” <unfinished …>
SYS_open(“/usr/lib/locale/locale-archive”, 32768, 01540) = 3
SYS_fstat64(3, 0xd301a0, 0xd2eff4, 0xd301a0, 0xd0fc60) = 0
SYS_mmap2(0, 0x200000, 1, 2, 3) = 0xb7d82000
SYS_mmap2(0, 204800, 1, 2, 3) = 0xb7d50000
SYS_mmap2(0, 4096, 1, 2, 3) = 0xb7d4f000
SYS_close(3) = 0
<... setlocale resumed> ) = “en_US”
# 以下略
利用例3: プログラムの経過時間を一緒に出力する(パフォーマンスチューニング用途など)
$ ltrace -tt -o log.txt ls / # マイクロ秒単位
19:56:53.267749 SYS_uname(0xbff417dc) = 0
19:56:53.267865 SYS_brk(NULL) = 0x9e12000
19:56:53.267917 SYS_access(0xbffdc1, 4, 0xc03fd4, 0xbffdc1, 4) = -2
# 以下略
-t にすると 19:56:53 のように秒単位、-tt にすると例のようにマイクロ秒単位、 -ttt にすると マイクロ秒単位で 1201517930.289331 のような UNIX タイムスタンプ形式になります。
tips – 実行時に共有ライブラリの優先順位を変える(シンボル重複時の動作)
Linux では複数の共有ライブラリ(*.so)に同じ関数が定義されている場合、重複する関数については先に読み込まれた共有ライブラリが利用され、その他のライブラリで定義される重複シンボルについては無視されます。
共有ライブラリのロード順序は ld でのリンク順になります。
また、既存の実行可能ファイルのロード順序を調べるには ldd を使います。
$ gcc src.c -o foo -lc -lm # libc.so, libm.so の順にロード
$ ldd foo # foo では libc.so が優先されていることを確認
libc.so.6 => /lib/tls/libc.so.6 (0x00c07000)
libm.so.6 => /lib/tls/libm.so.6 (0x00d35000)
/lib/ld-linux.so.2 (0x00bed000)
$ gcc src.c -o bar -lm -lc # 同じソースに対してリンク順序を入れ替えて bar 作成。
$ ldd bar # bar では libm.so が優先されていることを確認
libm.so.6 => /lib/tls/libm.so.6 (0x00d35000)
libc.so.6 => /lib/tls/libc.so.6 (0x00c07000)
/lib/ld-linux.so.2 (0x00bed000)
今回の本題、どうやって共有ライブラリを優先するかを実行時に決めるか?ですが、
LD_PRELOAD を使うことでコンパイル時のロード順を入れ替えることができます。
>
$ # LD_PRELOAD に /lib/tls/libc.so.6 (libc.so へのパス)を指定
$ LD_PRELOAD=/lib/tls/libc.so.6
$ ldd bar # 優先順位が変わっていることを確認
/lib/tls/libc.so.6 (0x00c07000)
libm.so.6 => /lib/tls/libm.so.6 (0x00d35000)
/lib/ld-linux.so.2 (0x00bed000)
ちなみに、LD_PRELOAD を設定すると、(setuid/setgid されたプログラムなど)一部を除くほとんどのプログラムで任意のライブラリを事前ロードできます。
これを利用すると任意のプログラムのライブラリ定義関数を置き換えることが可能です(参考:hook_tcp.so)。
参考:
– 共有ライブラリの作成(HP テクニカルドキュメント)
– hook_tcp.so(チームチドリ)
What is hook_tcp.so:
LD_PRELOADを利用して、プログラム中で実行される connect()の接続先をsyslogへ記録するプログラムです。
とのことで、libc.so の CONNECT(2) を hook して動作します。
– 4.17. LIDS を使う時は、LD_PRELOAD 環境変数に注意した方がいいですか?(LIDS FAQ)
tips – grep で前後の行も表示させるには
マッチ行直前の行を表示するには -B {行数}(または –before-context={行数})を、直後の行を表示するには -A {行数}(または –after-context={行数}) を指定します。
例: sh のマニュアル(manpage)から grep 検索する。
オプションなし(ただし -n は行番号を表示してわかりやすくするため付加しています)
$ man sh | grep -n UNIX
1378: A sh command, the Thompson shell, appeared in Version 1 AT&T UNIX. It
1379: was superseded in Version 7 AT&T UNIX by the Bourne shell, which inher-
1383: Bourne shell from AT&T System V.4 UNIX.
直前と直後 1 行ずつ表示
$ man sh | grep -n -A 1 -B 1 UNIX
1377-HISTORY
1378: A sh command, the Thompson shell, appeared in Version 1 AT&T UNIX. It
1379: was superseded in Version 7 AT&T UNIX by the Bourne shell, which inher-
1380- ited the name sh.
—
1382- This version of sh was rewritten in 1989 under the BSD license after the
1383: Bourne shell from AT&T System V.4 UNIX.
1384-
cygwin で nice
nice / renice を使うと起動するプロセスや起動済のプロセスの優先度を変更することができます。
nice の書式:
nice [-n 数値 ] 実行するコマンド [引数] ..
例:
$ nice -n 10 sleep 100 # nice 10 sleep 100 は間違い
renice: の書式:
renice 数値 [ [-p] PID ] [ [-g] pgrps] [ [-u] ユーザ]
指定した PID (またはプロセスグループ(PGID)、ユーザ)のプロセスの優先度を指定した数値に基づいて変更します。
Cygwin で実行する場合、PID にはWindows 上の実 PID (WINPID)ではなく、Cygwin で ps すると見られる仮想 PID を指定します。
例1: PID で指定
$ sleep 50 &
[1] 1448
$ renice 10 -p 1448
例2: PGID で指定
$ ps
PID PPID PGID WINPID TTY UID STIME COMMAND
2264 2248 2264 316 con 11363 13:31:29 /usr/bin/sleep
2168 2248 2168 2168 con 11363 13:31:33 /usr/bin/bash
2948 2168 2168 2920 con 11363 13:31:33 /usr/bin/sleep
$ renice 19 -g 2168 # PGID が 2168 の全てのプロセスが対象
例3: ユーザ名で指定( cygwin 経由で起動しているプロセスのうち実行ユーザが john のプロセス全ての優先度を -10 (通常以上)にする)
$ renice -10 -u john
Windows XP で実行した場合のプロセス優先度の対応表:
| nice -n | プロセス優先度 |
| 12以上 | 低 |
| 4 〜 11 | 通常以下 |
| -4 〜 3 | 通常 |
| -12 〜 -5 | 通常以上 |
| -19 〜-13 | 高 |
| -20 以下 | リアルタイム |
参考:
–起動するプログラムの優先度を変更する方法(@IT)
タスクマネージャを使った変更方法と、cmd.exe の start コマンドを使った優先度指定方法についてかかれています。