Linux上での検索のまとめ

# Linux上での検索のまとめ

Linux上で何か探したり、調べたりする手段のまとめ

## マニュアルを探す

分からないコマンドや用語がでてきたら、とりあえず`man`でマニュアルを引いてみる。
`man 調べたい単語`でマニュアルが表示される。
例えば、`man`コマンドそのものについて調べたい時

```bash
$ man man
```
カーソルの上下で行単位にスクロール。`ctrl-f`で次ページ、`ctrl-b`で前ページ
`/キーワード`で文中のキーワードの箇所にジャンプ、`q`で終了。
※この操作は後ででてくる`less`をはじめ、多くのコマンドで似たような動作をする。

### マニュアルがない場合はキーワード検索

該当する項目がなければ`-k キーワード`オプションをつけると
キーワードで指定した語句を含むマニュアルの一覧が表示される。

```bash
$ man password
password というマニュアルはありません
$ man -k password
vigr (8)             - password, group とそれぞれの shadow ファイルを編集する
vipw (8)             - password, group とそれぞれの shadow ファイルを編集する
crypt (3)            - password and data encryption
crypt_r (3)          - password and data encryption
endpwent (3)         - get password file entry
＜省略＞
```

一覧が流れてしまう場合は後ろに`| less`をつける

```bash
$ man -k password | less
```

これも、カーソルの上下で行単位にスクロール。`ctrl-f`で次ページ、`ctrl-b`で前ページ
`/キーワード`で文中のキーワードの箇所にジャンプ、`q`で終了。

### マニュアルの章

マニュアルの一覧に表示される`(3)`等の数字はマニュアルのsection、章を示す。
以下、`man man`から抜粋

```
1   実行プログラムまたはシェルコマンド
2   システムコール (カーネルが提供する関数)
3   ライブラリー呼び出し (プログラムライブラリーに含まれる関数)
4   特殊ファイル (通常 /dev 配下に存在するファイル)
5   ファイルの書式と慣習 (例: /etc/passwd)
6   ゲーム
7   その他いろいろなもの   (マクロパッケージや慣習などを含む)。  例えば  man(7)  や
    groff(7)。
8   システム管理コマンド (通常は root 用)
9   カーネルルーチン [非標準]
```

で、マニュアルを表示する場合、`man 数字 キーワード`で章を指定してマニュアルが表示される。

```bash:例
$ man passwd  # section1のpasswdのマニュアルが表示される
$ man 5 passwd  # section5のpasswdのマニュアルが表示される
```

## ファイルを検索したい

LinuxのHDDの中から、ある特定のファイルを探し出す手順。

- `which`はコマンドを名前で検索する
- `locate`はファイル名で検索する。ファイル名はバッチ処理でDB化されていて速い
- `find`はファイルの名前や日付などメタ情報で検索する
- `grep`はファイルの中身で検索する

### コマンドを検索（which）

環境変数`PATH`で設定されているディレクトリから指定された名前のコマンドを検索する
同名のコマンドを複数インストールしている場合などに、実際に使われているのがどれかを調べるのに使う。

```bash:コマンド検索
$ which python
~/.pyenv/shims/python
```

### ファイル名で検索（locate）

コマンドに限らず、名前からファイルを検索するには`locate`を使う。
locateはファイルの一覧を一日に一回程度のバッチ処理でDB化しているので、リアルタイムな検索はできない。
DBの更新は`updatedb`でできるが、それよりは後述の`find`を使う方がよい。

```bash:locateの例
$ locate syslog.conf
/etc/rsyslog.conf
/usr/lib/dracut/modules.d/98syslog/rsyslog.conf
/usr/share/doc/sudo-1.8.23/examples/syslog.conf
/usr/share/man/ja/man5/syslog.conf.5.gz
/usr/share/man/man5/rsyslog.conf.5.gz
```


### ファイル名で検索（find）

下記の書式で検索。検索場所はパスを指定（今いる場所なら`.`）、ファイル名はワイルドカードが使える（`*`で任意の文字列など）

```bash:書式
find 検索場所 -name ファイル名
```

```bash:例
find /usr -name *zip*
>> /usr/bin/unzip
>> /usr/bin/zip
>> /usr/lib/klibc/bin/gunzip
＜以下、略＞
```

### 日時で検索（アクセス日、更新日など）

最後にアクセスしたのが何日前かで検索する。今日は0で昨日は1

```bash:書式
find ディレクトリ -atime 日数
```

カレントディレクトリ以下で今日アクセスしたファイルを表示する

```bash:例
find ./ -atime 0
>> ./log
>> ./README.md
>> ./sample.jpg
```

何日以内の場合は日数にマイナスをつける
同様に何日前より以前にという場合はプラスをつける

```bash
find ./ -atime -3  # 3日以内にアクセスしたファイル
find ./ -atime +3  # 最終アクセスが3日以前のファイル
```

オプションを変えることで、単位や検索項目を変更できる
詳細は`man find`を参照

- 更新日で検索するには上記のatimeをmtimeに変更する
- 日付でなく、分で検索したい場合はatimeをaminにする

### ファイルの中身で検索

テキストファイルから文字列を検索するには`grep`コマンドを使う

```bash:基本形
$ grep 検索する文字列 対象のテキストファイル
```

/etc/以下の全てのファイルから'passwd'という文字列を検索して色付きで表示する例

```bash:色付きでサブディレクトリも検索
$ grep --color -sr passwd /etc/*
```

- -s：エラー表示をしない
- -r：サブディレクトリも検索する
- --color：色付きで表示する

表示が画面外に流れる場合は後ろに`| less`をつける

```bash:lessをつける
$ grep --color -sr passwd /etc/* | less
```

拡張子を指定する場合などは`include`を使う

```bash:拡張子を指定する
$ grep --color -sr passwd /etc --include="*.conf"
```

出力結果は`ファイル名:文字列を含む行`

```text:出力例
/etc/nsswitch.conf:passwd:     files sss
```

### grepの亜種

`man -k grep`でgrepの亜種コマンドが表示される。
詳細は`man コマンド名`を参照

```bash:grepの亜種の例
bzgrep (1)           - bzip2 圧縮されている可能性のあるファイルで、正...
egrep (1)            - パターンにマッチする行を表示する
fgrep (1)            - パターンにマッチする行を表示する
grep (1)             - パターンにマッチする行を表示する
pgrep (1)            - 名前や各種属性に基づくプロセスの閲覧とシグナ...
zgrep (1)            - 圧縮されている可能性のあるファイルで、正規表...
git-grep (1)         - Print lines matching a pattern
grep (1p)            - search a file for a pattern
grepdiff (1)         - show files modified by a diff containing a regex
msggrep (1)          - pattern matching on message catalog
pm-utils-bugreport-info.sh (8) - Print pm-utils bug report
Tcl_InvalidateStringRep (3) - manipulate Tcl objects
xzegrep (1)          - search compressed files for a regular expression
xzfgrep (1)          - search compressed files for a regular expression
xzgrep (1)           - search compressed files for a regular expression
zipgrep (1)          - search files in a ZIP archive for lines matching a pattern
```

### どこを探すか

どういうファイルがどの辺に置かれているのかの目安。

ファイルの種類 | 主な置き場所
:--|:--
設定ファイル | /etc/, /usr/local/etc
ドキュメントやconf | /usr/share, /usr/share/doc
通常のコマンド | /bin, /usr/bin, /usr/local/bin
その他のコマンド | /etc/rc.d, /usr/libexec
ライブラリのヘッダー(*.h) | /usr/include, /usr/local/include
ライブラリ本体(*.so) | /lib, /lib64, /usr/lib, /usr/lib64
ログ | /var/log

※/usr/local以下はBSD系のOSの場合、非常によく使われる。

## ログを探す

システムやサービスのエラーはログに記録される場合がおおい。そのログの探し方

### ログの場所

一般的には`/var/log`以下に置かれる。
`ls /var/log`で大体どのようなログがあるか一覧できる。

システム標準のログファイルについては`/etc/rsyslog.conf`で定義されており、下記のようなものがある。

```
/var/log/messages
/var/log/secure
/var/log/maillog
/var/log/cron
/var/log/spooler
/var/log/boot.log
```

他に下記のようなログもある

- /var/log/dmesg：OS起動時のブートログ
- /var/log/Xorg：Xwindow（GUI）のログ
- /var/log/yum.log：yumのログ（CentOSの場合）

### ログファイルから特定の語句を検索する

`grep`使う。検索語句にサービス名やログの種類（panic等）などを入れてみる
もしくはサービスのマニュアルや設定からログファイルを特定する
※ログファイルは一般ユーザーで読めない場合が多いので、sudoをつける

```bash
$ sudo grep httpd *
```

ログの種類（errやwarn等）はマニュアルを参照

```bash
$ man syslog.conf
```

### ログの最初や最後を表示する

ログファイルの中身を軽く確認したい場合。

```bash
$ sudo head messages
$ sudo tail messages
```

### ログをリアルタイムで監視する

ログファイルの更新をリアルタイムで検索したい場合

```bash
$ sudo tail -f /var/log/messages
```

更に、語句で絞り込みたい場合

```bash
$ sudo tail -f /var/log/messages | grep systemd
```