RNAseqの基本的な解析例

RNAseqの基本的な解析についてまとめてみました。
データはNBPSeqというパッケージに付属のarabを用いました。
これはシロイヌナズナ(Arabidopsis)のmutantとコントロールの二群から各々3つずつサンプリングされ、Illumina Genome Analyzer(http://www.illumina.com)によりシーケンスされたものです。

###データの読み込みと簡単な評価##

#NBPSeqをインストール&ロード
source("http://bioconductor.org/biocLite.R")
biocLite("NBPSeq")
library(NBPSeq)

#arabオブジェクトを生成
data(arab)

#arabの中身を頭出し
> head(arab)
mock1 mock2 mock3 hrcc1 hrcc2 hrcc3
AT1G01010 35 77 40 46 64 60
AT1G01020 43 45 32 43 39 49
AT1G01030 16 24 26 27 35 20
AT1G01040 72 43 64 66 25 90
AT1G01050 49 78 90 67 45 60
AT1G01060 0 15 2 0 21 8
#NGSのデータ特有の整数値が格納されていることが確認できる。

#arabオブジェクトの構造(各カラムのモード等)を表示
> str(arab)
int [1:26222, 1:6] 35 43 16 72 49 0 16 170 291 113 ...
- attr(*, "dimnames")=List of 2
..$ : chr [1:26222] "AT1G01010" "AT1G01020" "AT1G01030" "AT1G01040" ...
..$ : chr [1:6] "mock1" "mock2" "mock3" "hrcc1" ...



####データの可視化により定性的な評価を行う###

#サンプル間のすべての組み合わせに対してscatter plotを行い、technical duplicateとbiological duplicateのばらつきを評価する。
pairs(arab, log="xy", pch=16, cex=.3)


#hとmの各々について行の平均値を計算する
mean_m <- apply(arab, 1, function(x){mean(x[1:3])}) mean_h <- apply(arab, 1, function(x){mean(x[4:6])}) #MAプロットを行うために、M (log fold-change)とA (log intensity)を求める。 M <- log2(mean_h) - log2(mean_m) A <- 1/2 * (log2(mean_h) + log2(mean_m)) #MAプロットを行う plot(A, M, pch=16, cex=0.3, col="gray50",main="MA-plot:moc vs hrc) #M=0の高さに水平線を引く。 abline(h=0, col=4, lty=2)




###5倍以上の発現変動があった遺伝子をピックアップする。###

#これまでの計算結果をひとつのテーブルにまとめる
arab_summary <- data.frame(arab, mean_m, mean_h, M, A) #各行で発現変動があったかどうかを調べて二値で表す。(RPKMなどの手法で正規化を行っていない生データに対して解析を行うのは乱暴であるが。。) > head(M >= log2(5))
AT1G01010 AT1G01020 AT1G01030 AT1G01040 AT1G01050 AT1G01060
FALSE FALSE FALSE FALSE FALSE FALSE
#5倍以上の発現変動があった遺伝子を抽出し、新たなテーブルを作成
five_fold <- subset(arab_summary, arab_summary$M >= log2(5))

#MA-plotを描写して、5倍異常の発現変動があった遺伝子を赤くマーキングする
plot(arab_summary$A, arab_summary$M, pch=16, cex=0.3, col="gray50")
points(five_fold$A, five_fold$M, col="red", pch=16, cex=0.4)


#倍数変化の手法だと、発現値の低い遺伝子(ばらつきの大きな傾向にあります)にたくさんの偽陽性が含まれて、
#発現値の高い遺伝子(ばらつきが小さい傾向にあります)に偽陰性がたくさんふくまれてしまいます。
#しっかりデータ全体にたいして正規化を行った後、t-testなどでp値を用いた検定を行い、その両者の共通項を探しにいくのが無難かと思われます。

ファイルサイズを調べる

lsに-hlというオプションを付けると、各ファイルサイズに単位をつけて表示してくれます。

Rのedit関数

RのオブジェクトをWindowsのECELをいじる感覚で、直接編集してしまいたい場合は、edit関数を使います。


すると、vimがたちあがり、直接数値をいじることができます。

もちろん、「:wq」で保存して終了します。

マニュアルページのソースを理解する

使用方法の正確には理解できていないコマンドはmanコマンドにより、マニュアルを参照することになります。

今回は、そのマニュアルコマンドが参照する元ネタのファイルについて勉強しました。

lsコマンドのマニュアルファイルを例にとってみます。

まず、マニュアルは以下の9章に分けられて記述されています。

$ man man

1 実行プログラムまたはシェルのコマンド
2 システムコール (カーネルが提供する関数)
3 ライブラリコール (システムライブラリに含まれる関数)
4 スペシャルファイル (通常 /dev に置かれている)
5 ファイルのフォーマットとその約束事。例えば /etc/passwd など
6 ゲーム
7 マクロのパッケージとその約束事。例えば man(7), groff(7) など
8 システム管理用のコマンド (通常は root 専用)
9 カーネルルーチン [非標準]

lsは実行プログラムであり、シェルのコマンドであるので、第一章すなわちman1のディレクトリに置いてあることが予想されます。


manのパスは/etc/manpath.configというファイルに記述されています。
$ less /etc/manpath.config

# *PATH* -> *MANPATH*
#
MANPATH_MAP /bin /usr/share/man
MANPATH_MAP /usr/bin /usr/share/man
MANPATH_MAP /sbin /usr/share/man
MANPATH_MAP /usr/sbin /usr/share/man
MANPATH_MAP /usr/local/bin /usr/local/man
MANPATH_MAP /usr/local/bin /usr/local/share/man
MANPATH_MAP /usr/local/sbin /usr/local/man
MANPATH_MAP /usr/local/sbin /usr/local/share/man
MANPATH_MAP /usr/X11R6/bin /usr/X11R6/man
MANPATH_MAP /usr/bin/X11 /usr/X11R6/man
MANPATH_MAP /usr/games /usr/share/man
MANPATH_MAP /opt/bin /opt/man


lsのパスは
$ which ls
/bin/ls
なので、/usr/share/manのディレクトリ下にあると考えられる。

$ cd /usr/share/man
$ cd man1
$ pwd
/usr/share/man/man1

lsとついているファイルを表示
$ ls | grep ls
alsactl.1.gz
alsamixer.1.gz
dpkg-gensymbols.1.gz
false.1.gz
fslsfonts.1.gz
hp-levels.1.gz
ls.1.gz
lsattr.1.gz
lsb_release.1.gz
lscpu.1.gz
lsdiff.1.gz
lshw.1.gz
lspgpot.1.gz
lss16toppm.1.gz
lsusb.1.gz
md5sum.textutils.1.gz
mtools.1.gz
mtoolstest.1.gz
mysqlshow.1.gz
mysqlslap.1.gz
ppmtolss16.1.gz
pulseaudio.1.gz
smbcacls.1.gz
system-tools-backends.1.gz
tclsh-default.1.gz
tclsh.1.gz
tclsh8.4.1.gz
tclsh8.5.1.gz
xlsatoms.1.gz
xlsclients.1.gz
xlsfonts.1.gz



ls.1.gzがおそらく、lsのマニュアルであろうと考えられるので、ホームディレクトリにコピーして展開
$ cp ls.1.gz ~
$ cd ~
$ gunzip ls.1.gz
$ ls | grep "ls"
ls.1
$ less ls.1
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.35.
.TH LS "1" "June 2010" "GNU coreutils 8.5" "User Commands"
.SH NAME
以下続く


マニュアルは、manコマンド固有の文法でかかれているようである。
makefileとこの点は類似しています。
ちょっと調べたところ、groffコマンドをフィルタにすれば可読な文に翻訳できることがわかった。

$ groff -Tascii -man ls.1 | less

]LS(1) User Commands LS(1)



NAME
ls - list directory contents

SYNOPSIS
ls [OPTION]... [FILE]...

DESCRIPTION
List information about the FILEs (the current directory by default).

続く・・・



結構シンプルな仕組みですね。

でしたら、以前自分で作ったhello(/bin/hello)プログラムに関してのオンラインマニュアルを作成して、/usr/share/man/man1/に置いてやれば、manコマンドの引数とすることができるはずです。

$ vim hello.1
$ ls hello.1
.TH HELLO 1
.SH NAME
HELLO \- A simple greeting application that only geets.

.SH AUTHOR
KAPPA

$ gzip hello.1
$ ls
hello.1.gz
#/usr/share/man/man1/へコピー
$ sudo hello.1.gz /usr/share/man/man1

#テストしてみます。
$ man hello

HELLO(1) HELLO(1)

NAME
HELLO - A simple greeting application that only geets.

AUTHOR
KAPPA

HELLO(1)

うまくいきました。


ソフトウェアをマニュアルも一緒に配布しようと考える場合は、今回の操作をMakefileに書き込んでおけばいいのかな?
Configureスクリプトでマニュアルのパスを調べるようにしておくのかな?

現段階の理解では、まだよく分かりません。

Manコマンドを日本語化

ubuntuに限られると思いますが、以下の一行をターミナルで入力してもらえば、日本語化が完了します。

sudo aptitude install manpages-ja

Makefileにinstallの記述を行う

前回の投稿で作成したhelloという実行ファイルをパスの通ったディレクトリに自動的に置いてあげるルールを作成してみます。
これこそが世間一般で言うインストールというものです。

まず最初に、私たちが毎日のように用いているLinuxコマンドの一つ「ls」の実行ファイルのパスを調べます。

$ which ls
/bin/ls

#/bin/には、grepやkillなどの馴染み深いコマンドの実行ファイル(コマンド本体)がいっぱい置いてあります。
$ ls /bin
bash date gzip mt readlink uname
bunzip2 dbus-cleanup-sockets hostname mt-gnu rm uncompress
busybox dbus-daemon ip mv rmdir unicode_start
bzcat dbus-uuidgen kbd_mode nano rnano vdir
bzcmp dd kill nc run-parts vmmouse_detect
bzdiff df less nc.openbsd sed which
bzegrep dir lessecho netcat setfont ypdomainname
bzexe dmesg lessfile netstat setupcon zcat
bzfgrep dnsdomainname lesskey nisdomainname sh zcmp
bzgrep domainname lesspipe ntfs-3g sh.distrib zdiff
bzip2 dumpkeys ln ntfs-3g.probe sleep zegrep
bzip2recover echo loadkeys ntfs-3g.secaudit static-sh zfgrep
bzless ed login ntfs-3g.usermap stty zforce
bzmore egrep lowntfs-3g open su zgrep
cat false ls openvt sync zless
chgrp fgconsole lsmod pidof tailf zmore
chmod fgrep mkdir ping tar znew
chown fuser mknod ping6 tempfile
chvt fusermount mktemp plymouth touch
cp grep more ps true
cpio gunzip mount pwd ulockmgr_server
dash gzexe mountpoint rbash umount

#/bin/に自分が作る新しい実行ファイルを追加するためには、/binの属性を調べる必要があります
$ ls -l / | grep "bin"
drwxr-xr-x 2 root root 4096 2012-03-01 08:07 bin
drwxr-xr-x 2 root root 4096 2012-03-16 00:21 sbin

#/binディレクトリは、rootユーザーの所有であり、それ以外のユーザーは閲覧したり、実行したりすることは出きるが、上書きすることができないということがわかる。故に、Makefileのルールに従い、実行ファイルまでは作成できるものの、「インストール」をしようとして、/bin/に実行ファイルを置こうものなら、ルート権限が要求されることが理解できる。

それでは実際にMakefileにInstallのルールを追記してみる。


$ cat Makefile
#Makefile

#マクロを定義します
TARGET = hello
OBJECT = hello.o
SRC = hello.c
CC = gcc
CFLAGS = -g -Wall

#コマンド行
#以下の二行の繰り返し
#1.ターゲット: 依存するファイルの形式で記述する
#2.(Tabの後) コマンド
$(TARGET) : $(OBJECT)
@echo "*** Making $(TARGET) ****" #make実行中にコメントを表示
$(CC) -o $(TARGET) $(OBJECT)
$(OBJECT) : $(SRC)
@echo "*** Making $(OBJECT) ****" #make実行中にコメントを表示
$(CC) -c $(SRC)
clean:
@echo "*** Deleting $(OBJECT) ***"
rm -f $(OBJECT)
clobber: clean
@echo "*** Clobbering all produced files : $(OBJECT),$(TARGET)"
rm -f $(TARGET)
#もしも万が一、同名の実行ファイルがすでに/binに存在する場合は、警告を出すように-iオプションをつける。
install:
cp -ip $(TARGET) /bin

$ make
*** Making hello.o ****
gcc -c hello.c
*** Making hello ****
gcc -o hello hello.o


$ make install
cp -ip hello /bin
cp: 通常のファイル `/bin/hello' を作成できません: 許可がありません
make: *** [install] エラー 1

$ sudo make install

$ sudo make install
[sudo] password for user:
cp -ip hello /bin

#パスをつけずに実行ファイルを実行してみる。
#パスが通って入れば、実行されるはず。。。。
$ hello
Hello, world!!

#ばっちりですね!!!
#念のためhelloへのパスを調べてみると
$ which hello
/bin/hello

#しっかり目的の場所に実行ファイルが置かれていることがわかります。


/binにおいておけば、自分以外のユーザーもアクセスできるため、プログラムを共有して使うことができるのですね。
いかにもUNIXらしいシステムです。

今日はちょっと感動しました。

makeを使ってビルドを楽に♪

UNIXにプログラムを追加するときに、ソースコードからコンパイルすることが多々あります。
今回は、ソースコードからインストールするときに用いるmakeコマンドについて勉強しました。

まず、hello, worldを普通にコンパイルしてみます。
-cオプションを付けてオブジェクトファイルを一度生成しているところに注意します。

$ ls
hello.c
$ cat hello.c
#include
int main(void)
{
printf("Hello, world!!\n");
return 0;
}

$ gcc -c hello.c
$ ls
hello.c hello.o
$ gcc -o hello hello.o
$ ls
hello hello.c hello.o
$ ./hello
Hello, world!!





次に上の手続きを一つのファイル(Makefile)に記述して、makeコマンドにより同様の処理を行ってみます。
$ ls
Makefile hello.c
$ cat Makefile
#Makefile

#以下の二行の繰り返し
#1.ターゲット: 依存するファイルの形式で記述する
#2.(Tabの後) コマンド
hello : hello.o
gcc -o hello hello.o
hello.o : hello.c
gcc -c hello.c

$ make
gcc -c hello.c
gcc -o hello hello.o
$ ls
Makefile hello hello.c hello.o
$ ./hello
Hello, world!!




次に、make実行中にコメントを表示させてみます。
一般的なプログラムをコンパイルしているときにもコメントが出ますよね。
$ cat Makefile
#Makefile

#以下の二行の繰り返し
#1.ターゲット: 依存するファイルの形式で記述する
#2.(Tabの後) コマンド
hello : hello.o
@echo "*** Making hello ****"
gcc -o hello hello.o
hello.o : hello.c
@echo "*** Making hello.o ****"
gcc -c hello.c

$ make
*** Making hello.o ****
gcc -c hello.c
*** Making hello ****
gcc -o hello hello.o
$ ls
Makefile hello hello.c hello.o
$ ./hello
Hello, world!!






次に、メイクファイルにマクロを定義してみます。
マクロを定義することで、処理系の異なる環境でも、makeファイルの変更点を最小限に止めることができます。

$ cat Makefile
#Makefile

#マクロを定義します
TARGET = hello
OBJECT = hello.o
SRC = hello.c
CC = gcc
CFLAGS = -g -Wall

#コマンド行
#以下の二行の繰り返し
#1.ターゲット: 依存するファイルの形式で記述する
#2.(Tabの後) コマンド
$(TARGET) : $(OBJECT)
@echo "*** Making $(TARGET) ****" #make実行中にコメントを表示
$(CC) -o $(TARGET) $(OBJECT)
$(OBJECT) : $(SRC)
@echo "*** Making $(OBJECT) ****" #make実行中にコメントを表示
$(CC) -c $(SRC)
$ make
*** Making hello.o ****
gcc -c hello.c
*** Making hello ****
gcc -o hello hello.o
$ ls
Makefile hello hello.c hello.o
$ ./hello
Hello, world!!




最後に、作成したオブジェクトファイルや実行ファイルを清掃(削除)するためのルールを追記します。
cleanとclobberです。
cleanは、オブジェクトファイルの削除。
clobberは、cleanの手続きに加えて、指定したファイルの削除を行います。ここでは、実行ファイル(hello)削除しています。
$ cat Makefile
#Makefile

#マクロを定義します
TARGET = hello
OBJECT = hello.o
SRC = hello.c
CC = gcc
CFLAGS = -g -Wall

#コマンド行
#以下の二行の繰り返し
#1.ターゲット: 依存するファイルの形式で記述する
#2.(Tabの後) コマンド
$(TARGET) : $(OBJECT)
@echo "*** Making $(TARGET) ****" #make実行中にコメントを表示
$(CC) -o $(TARGET) $(OBJECT)
$(OBJECT) : $(SRC)
@echo "*** Making $(OBJECT) ****" #make実行中にコメントを表示
$(CC) -c $(SRC)
clean:
@echo "*** Deleting $(OBJECT) ***"
rm -f $(OBJECT)
clobber: clean
@echo "*** Clobbering all produced files : $(OBJECT),$(TARGET)"
-rm -f $(TARGET)

$ ls
Makefile hello.c
$ make
*** Making hello.o ****
gcc -c hello.c
*** Making hello ****
gcc -o hello hello.o
$ ls
Makefile hello hello.c hello.o
$ ./hello
Hello, world!!
$ make clean
*** Deleting hello.o ***
rm -f hello.o
$ ls
Makefile hello hello.c
$ make
*** Making hello.o ****
gcc -c hello.c
*** Making hello ****
gcc -o hello hello.o
$ ls
Makefile hello hello.c hello.o
$ make clobber
*** Deleting hello.o ***
rm -f hello.o
*** Clobbering all produced files : hello.o,hello
rm -f hello
$ ls
Makefile hello.c




今回のMakefileには、Linuxコマンドはgccとrmしか登場してきていません。
しかし、Makefileには好きなコマンドを書けば、勝手に実行してくれます。
makeの最後にRを実行するMakefileを作成して実行してみます。



$ cat Makefile
#Makefile

#以下の二行の繰り返し
#1.ターゲット: 依存するファイルの形式で記述する
#2.(Tabの後) コマンド
#一番最後にRの実行をしているところに注意してください。
hello : hello.o
gcc -o hello hello.o
hello.o : hello.c
gcc -c hello.c
R

$ make
gcc -c hello.c
R

R version 2.11.1 (2010-05-31)
Copyright (C) 2010 The R Foundation for Statistical Computing
ISBN 3-900051-07-0

Rは、自由なソフトウェアであり、「完全に無保証」です。
一定の条件に従えば、自由にこれを再配布することができます。
配布条件の詳細に関しては、'license()'あるいは'licence()'と入力してください。

Rは多くの貢献者による共同プロジェクトです。
詳しくは'contributors()'と入力してください。
また、RやRのパッケージを出版物で引用する際の形式については
'citation()'と入力してください。

'demo()'と入力すればデモをみることができます。
'help()'とすればオンラインヘルプが出ます。
'help.start()'でHTMLブラウザによるヘルプがみられます。
'q()'と入力すればRを終了します。

> q()
Save workspace image? [y/n/c]: n
gcc -o hello hello.c
$ ls
Makefile hello hello.c hello.o


オブジェクトファイルが作られてから、Rが実行され、Rを抜けてから、実行ファイルが生成されていることがわかります。

EasyLFS

EasyLFS

のISOファイルをダウンロードしてきて、virtualboxにインストール。
ログインはrootでパスワードはデフォルトのeasylfsです。
次の日記に書く方法で、仮想HDDを追加して(/dev/hda)、それをパーティショニングする。

# fdisk /dev/hda

> p #パーティションテーブルを表示させる。

> n #パーティションナンバー1を追加
> n #パーティションナンバー2を追加
> t #パーティションナンバー2の属性を82に変更してやり、swap領域とする。
82

次にインストールスクリプトのあるディレクトリに移動

# cd /lfs-install

インストールの設定ファイルの変更
# vim lfs_config.sh


Target-partitionだけ変更した。
Default: LFS_DEV/=dev/hda1


あとは、シェルスクリプトを実行するだけ。
# ./lfs-install.sh

Virtual Box上で、仮想ハードディスクを追加する

Linux from Scratchを
仮想環境で構築したい関係で、

複数の仮想ハードディスクを管理する必要が出てました。


方法は、

1 設定画面で、仮想OSを選択
2 「設定」「ストレージ」「IDEコントローラー」「HDDの追加」「新規ディスクの作成」「VDI」「固定」「サイズを決定する」

3 仮想OSを起動する
4 $ sudo fdisk /dev/hda
> p #パーティションテーブルを見る


以上です。

今回追加した仮想HDDはIDEコントローラーを用いたために、/dev/hdaとなりましたが
SATAコントローラーを用いれば、/dev/sdaとなることが予想されます。

scanfの戻り値を調べてみた_その2

scanf関数の戻り値について若干追記します。

調べたところによると
scanf関数の戻り値は、正常に取得できたデータの個数だそうです。
ですので以下のプログラムでは、a,b,cに正しく整数値を格納できたときのscanfの戻り値は3になります。
異常が生じたときは、正常な個数だけ値が戻されます。

/* three.c */
#include


int main(void)
{
int a,b,c;
int x;

x = scanf("%d%d%d", &a,&b,&c);
printf("Your data is : %d %d %d\n", a,b,c);
printf("Scanf returned %d\n", x);

return 0;
}


$ gcc -o three three.c


$ ./three
1
2
6
Your data is : 1 2 6
Scanf returned 3
$ ./three
3
5
q
Your data is : 3 5 15552500
Scanf returned 2
$ ./three
2
q
Your data is : 2 134513824 4448244
Scanf returned 1
$ ./three
1
q
Your data is : 1 134513824 2527220
Scanf returned 1
$ ./three #EOFを入力してみる
Your data is : -1076778936 134513824 3690484
Scanf returned -1

scanfの戻り値を調べてみた

scanf関数は、C言語の入門編で頻出の関数です。
whileのループとの組み合わせで用いられることが多い気がしましたので、
そのメカニズムについて検証してみました。

まずは以下のプログラムを作成しました。

/* scanf_test.c */
#include

int main(void)
{
int a;
int b;

printf("Enter integer data.\n");
b = scanf("%d", &a);

printf("a = %d\n", a);
printf("b = %d\n", b);

return 0;
}


これをscanf_testをコンパイルしてscanf_testという実行ファイルを生成したとします。
以下のようにしてscanf_testプログラムを通じて、scanf関数の戻り値(bに格納されている)をテストしてみました。

$ ./scanf_test
Enter integer data.
20
a = 20
b = 1
$ ./scanf_test
Enter integer data.
0
a = 0
b = 1
$ ./scanf_test
Enter integer data.
-3
a = -3
b = 1
$ ./scanf_test
Enter integer data.
T
a = 7864308
b = 0
$ ./scanf_test
Enter integer data.   ##ここではCntrol + D(End Of File)を入力している
a = 16359412
b = -1

aをint型で宣言したので、それに不適合な変数が格納されようとすると、scanfは0や-1を返すようです。

この性質を利用すれば、whileループと組み合わせて、効率よく目的のデータ型の変数を取得できます。

/* scanf_test_2.c */
#include
int main(void)
{
int a;
int b;
printf("Enter integer data.\n");
printf("Enter q(別に数字以外ならなんでもいいけど) to quit the program.\n");
while(scanf("%d",&a) == 1){
printf("Your input data is %d\n", a);
}
return 0;
}



$ ./scanf_test_2
Enter integer data.
Enter q(別に数字以外ならなんでもいいけど) to quit the program.
3
Your input data is 3
0
Your input data is 0
-4
Your input data is -4
q

ncbiのftpサーバーからzebrafishの全遺伝子情報をとってくる

#ftpサーバーに接続
$ ftp ftp ftp.ncbi.nih.gov

ftp> ls
ftp> cd refseq
ftp> ls
ftp> cd D_rerio
ftp> get README
ftp> cd mRNA_Prot
ftp> ls
ftp> get zebrafish.rna.fna.gz
ftp> quit

$ gunzip zebrafish.rana.fna.gz

$ less zebrafish.rana.fna

Linuxコマンドのソースコードを見てみる。

徳にDeveloperであるわけではないのだが、
いやむしろLinux初心者であるわけだが、
Linuxのコマンドや標準Cライブラリのソースコードを見ることにとても憧れています。
ソースコードをビルドするときに
リンクされているバイナリファイルたち。。


コマンドのソースはGNUに置いてあります。

$ wget http://ftp.gnu.org/gnu/coreutils/coreutils-8.4.tar.gz
$ tar xzvf coreutils-8.4.tar.gz
$ cd coreutils-3.4/src
#興奮の瞬間。catのソースをとりあえずみてみる。
$ less cat
$ ../lib
#ここには標準Cライブラリのソースコードがいっぱい
#やっほい!!!
#楽しすぎる!!!!

manコマンドを大切にしたい

$ man man
で表示される下記の9項目を意識してLinuxを操りたいものだ。

1 実行プログラムまたはシェルのコマンド
2 システムコール (カーネルが提供する関数)
3 ライブラリコール (システムライブラリに含まれる関数)
4 スペシャルファイル (通常 /dev に置かれている)
5 ファイルのフォーマットとその約束事。例えば /etc/passwd など
6 ゲーム
7 マクロのパッケージとその約束事。例えば man(7), groff(7) など
8 システム管理用のコマンド (通常は root 専用)
9 カーネルルーチン [非標準]