> For the complete documentation index, see [llms.txt](https://hayashier.gitbook.io/article/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://hayashier.gitbook.io/article/system-admin/troubleshooting-linux.md).

# よく使うトラブルシューティング コマンド実行例 まとめ

## ファイル

* ファイル名検索

```
$ find ./ -name hoge
```

* 任意のファイルから特定文字列を検索

```
$ grep -r hoge ./
```

* ファイルサイズが大きい順に表示

```
$ du -sh * | sort -h -r
```

* 1秒おきにコマンド継続実行

```
$ while true; do sleep 1; echo hello; done
```

* ディスク使用量確認

```
$ sudo ionice -c 2 -n 7 nice -n 19 du -scm /* | sort -rn
```

* パーティション毎のディスク使用量確認

```
$ df -Th
```

* メモリ使用量

```
$ free -m
```

* Swapサイズ

```
$ swapon -s
```

### /proc/

* CPU情報、コア数など

```
$ less /proc/cpuinfo
```

* メモリ使用内訳

```
$ less /proc/meminfo
```

* OS内で動作するすべてのプロセスにおけるinotify watch数を把握

```
$ ls -l /proc/*/fd/ | grep inotify | wc -l
```

### プロセス

* プロセス数を確認

```
$ ps auxww
```

* 使ってるファイルのプロセスを調べる

```
$ lsof -p PID番号
```

* /bin/shで動いてるプロセスを全て停止する

```
$ pkill -f /bin/sh
$ ps auxww | grep /bin/sh | awk '{print $2}' | xargs kill
```

## バージョン

* OSバージョン

```
$ cat /etc/redhat-release
```

* kernelバージョンを調べる

```
$ uname -a
```

* パッケージの確認

```
$ rpm -qa
```

* プロセスが掴んでいるファイル一覧

```
$ sudo ls -l /proc/2676/fd
```

* プロセス内のスレッドの数

```
$ ps aux -L
```

* 稼動しているプロセスを検索

```
$ pgrep -l syslog
```

* プロセスの親子関係

```
$ pstree
```

### ls系

* PCI バスとそこにつながっているデバイス

```
$ lspci
```

* CPUの情報

```
$ lscpu
```

* ブロックデバイスのリスト

```
$ lsblk
```

* ロードされているカーネルモジュール

```
$ lsmod
```

### dmidecode

* システムの情報、型番等

```
$ dmidecode -t system
```

* BIOS の情報

```
$ dmidecode -t bios
```

* CPU の情報

```
$ dmidecode -t processor
```

* メモリの情報

```
$ dmidecode -t memory
```

## パフォーマンス

![Linux Performance Observability Tools](https://www.brendangregg.com/Perf/linux_observability_tools.png)

* References
  * [Linux Performance](http://www.brendangregg.com/linuxperf.html)

## 監査

### auditd

`/etc/audit/rules.d/audit.rules`ファイルの末尾に、以下の行を追加しOSを再起動

```
-a entry,always -F arch=b64 -S kill -k MyKillTrace 
```

以後、`/var/log/audit/audit.log` にkillシステムコールを呼び出したプロセスの情報が記録される。以下のようにコマンドで対象のプロセスが発行したkillシステムコールをログに出力。

```
# strace -fttvo ログファイル名 -s 1000 -e kill -p プロセスID
```

## ネットワーク

### General

* CPU使用率

```
$ vmstat 5
$ sar -p 5
```

* 特定のユーザーが使用しているCPU使用率

```
$ top -u oracle
```

* CPU使用率 Top15

```
$ top -H -b -n1 | head -15
```

* ディスクI/O使用率

```
$ vmstat -d
```

### 接続性

* traceroute

```
$ sudo traceroute -T -p 443 192.168.0.1
```

* Nping

```
$ sudo nping 192.168.0.1 --tcp -p 443 -c 30
```

* MTR

```
$ mtr --report -c 100 --no-dns github.com
```

### コマンド別

#### netstat

* TCPの接続状態確認

```
$ netstat -lanpt
```

* LISTEN/ESTABLISHEDの状態(Openな接続)確認

```
$ netstat -an
```

* ネットワークに正常にパケットが送受信できているか

```
$ netstat -i
```

* 接続元のユニークなIP IPv4

```
$ netstat -nA inet | awk '/^[ut]/{split($5,a,:);print a[1]}'|sort |uniq -c |sort -n > ip-2.txt
```

IPv6

```
$ netstat -nA inet6 | awk '{print $5}' | sed s/::ffff:// | cut -d: -f1 | sort | uniq -c | sort -n > ip6-2.txt
```

#### ss

* オープンな接続数の調査

```
$ ss -a | wc -l
```

* TCPのみフィルタリング

```
$ ss -t | wc -l
```

* TCPの状態でフィルタリング

```
$ ss state time-wait | wc -l
```

#### curl

* ヘッダーだけ表示

```
$ curl -v -s www.google.com > /dev/null
$ curl -v -so /dev/null www.google.com
```

* ヘッダー指定

```
$ curl -v -s -H Host: www.google.com clb.test.hayashier.com > /dev/null
```

* 時間測定

```
$ curl -s -o /dev/null -w %{time_total} http://www.google.com
```

* 詳細時間表示

```
$ curl -w %{remote_ip} time_namelookup: %{time_namelookup} tcp: %{time_connect} ssl:%{time_appconnect} start_transfer:%{time_starttransfer} total:%{time_total}\n -sk -o /dev/null http://www.google.com
```

* POSTメソッド

```
$ curl --request POST 'http://www.google.com' --data hoge=fuga
```

動画ファイルのPOST

```
$ curl -v -F video=@Downloads/test.mp4 -X POST http://test.hayashier.com
```

* Cookie 送信

```
$ curl -v --cookie HOGE=FUGA http://clb.test.hayashier.com
```

* ラウンドロビンDNSの調査

```
$ curl -IsSv <FQDN> 2>&1 | grep Trying
```

* レスポンスコード調査し続ける

```
$ IsError=false; while [ $IsError != true ]; do curl -I -k <URL> 2>&1 | tee error.out | grep HTTP/1.1  ; done;
```

スリープ付き

```
$ IsError=false; while [ $IsError != true ]; do sleep .5; (time curl -I -k <URL>) 2>&1; done;
```

* 連続でリクエスト送信時のステータスコードと処理時間

```
$ while true; do curl -s -o /dev/null -w HTTPCode=%{http_code} TotalTime=%{time_total}\n http://www.google.com; done
```

* 5秒おきにリクエスト送信時のヘッダー情報

```
$ while true; do curl -I -L http://www.google.com/; sleep 5; done
```

* HTTP/2でテスト

```
$ curl --http2 -I https://twitter.com
```

* スクリプトと合わせてテスト

```
$ curl -v -H 'TEST: '$(perl -e 'print 0x16376') http://test.hayashier.com
```

* 表示項目 カスタマイズ 以下の内容を curl-format.txt として保存。

```
\n
Timing:\n
DNS Resolution Time:  %{time_namelookup}\n
TCP Handshake:    %{time_connect}\n
SSL Handshake:    %{time_appconnect}\n
time_pretransfer: %{time_pretransfer}\n
time_redirect:    %{time_redirect}\n
time_starttransfer: %{time_starttransfer}\n
---------------------------------------------\n
Total Time spent: %{time_total}\n
\n
HTTP Details:\n
HTTP Status Code: %{http_code}\n
Request Size:   %{size_request}\n
\n

```

```
$ curl -w '@curl-format.txt' -L https://google.com -so /dev/null


Timing:
DNS Resolution Time:  0.030453
TCP Handshake:    0.044017
SSL Handshake:    0.087345
time_pretransfer: 0.087440
time_redirect:    1.848814
time_starttransfer: 0.331126
---------------------------------------------
Total Time spent: 3.383122

HTTP Details:
HTTP Status Code: 200
Request Size:   152
```

* ネームサーバ 接続テスト

```
$ while true; do curl --connect-timeout 5 -o /dev/null -Ssk -H Host: api.github.com https://192.30.255.116/ && echo ok; sleep 1; done
```

#### dig

* ELBノード毎のレスポンスのHTTPステータス

```
$ dig +short +noall +answer alb.test.hayashier.com | xargs -L 1 curl -vG 2>&1 >/dev/null | awk '/^(< HTTP|> Host)/ { print $3 }'
```

* ネームサーバ IP 列挙

```
$ for j in `dig +short  ns github.com.`; do dig @$j +short api.github.com.; done
```

#### OpenSSL

* 接続テスト

```
$ openssl s_client -connect clb.test.hayashier.com:443

GET / HTTP/1.1
```

* 証明書詳細

```
$ openssl s_client -showcerts -connect <host>:<port> < /dev/null
```

* 暗号スイート指定

```
$ openssl s_client -cipher 'ECDHE-ECDSA-AES256-SHA' -connect clb.test.hayashier.com:443 
```

#### Netcat

* クライアント/サーバ間通信

```
$ nc -v -l -k 1234
Connection from 127.0.0.1 port 1234 [tcp/search-agent] accepted
Hi
World

Connection from 127.0.0.1 port 1234 [tcp/search-agent] accepted
GET / HTTP/1.1
Host: localhost:1234
User-Agent: curl/7.51.0
Accept: */*

Connection from 127.0.0.1 port 1234 [tcp/search-agent] accepted
POST / HTTP/1.1
Host: localhost:1234
User-Agent: curl/7.51.0
Accept: */*
Content-Length: 9
Content-Type: application/x-www-form-urlencoded

hoge=fuga
```

```
$ nc localhost 1234 -v
Connection to localhost 1234 port [tcp/search-agent] succeeded!
Hi
World
```

* 接続状態監視

```
$ while true ; do echo -n $(date): ; nc -vz api.github.com 443; sleep 2; done
```

* 時刻変換

```
$ date --date='@1527718243'
Thu May 31 07:10:43 JST 2018
```

### Others

* [nicolaka/netshoot](https://hub.docker.com/r/nicolaka/netshoot)

## 低レイヤー

### strace

* `ps aux`で対象プロセスの`PID`よりプロセスIDを確認して、`-p`オプションで指定して動きをトレース
  * 例えば、Nginxのworkerのネットワーク関連にシステムコールの動きをトレースする場合は以下のように実行

    ```
    $ sudo strace -p 5 -e trace=network
    ```
  * 問題発生時に書くシステムコールで要した時間を確認したい場合は、以下のように実行
    * `-e trace=xxxx`で指定した
    * `-tt`でusecでタイムスタンプを絶対時間で表示
    * `-T`で各システムコールで要した時間
    * `-o FILE_NAME`で結果を指定したファイルに出力

      ```
      $ sudo strace -T -tt -e trace=all -p 460 -o output.txt
      ```

### gdb

* 実行プロセスのコードを追う

  ```
  $ gdb -p `ps aux | grep redis-server | grep -v grep | awk '{print $2}'`
  ```
* Tips
  * ブレークポイントを打つ点は、`bt`コマンドでデバッグトレースを確認し、毎回通過する関数などを観察すると良い（Redisの場合は、`processCommand`）。

※Redisサーバーをデバッグするためには、手動でビルドする必要があります。その際、`make CFLAGS="-g "`のように実行しておく必要があります。適宜Makefileの`OPTIMIZATION?`の値で`-O2`から`-O0`に変更しておくとよいでしょう。

* References
  * [Dive Deep Redis Internals \~ GETコマンド実行時の動作 \~](https://hayashier.com/article/dive-deep-redis/)

## 負荷テスト

```
$ h2load -n 10000 -c 10 -m 10 -v -p h2c https://test.hayashier.com
$ ab -n 10000 -c 10 -k https://test.hayashier.com
```

* sysbench インストール

```
$ curl -s https://packagecloud.io/install/repositories/akopytov/sysbench/script.rpm.sh | sudo bash
$ sudo yum -y install sysbench
```

実行方法

```
$ sysbench --test=cpu run
```

## パケットキャプチャ　

* 取得

```
$ sudo tcpdump -w sample.pcap
```

* フィルター例

sample.pcapというpcapファイルを読み込み(-rオプション)、DNSに変換せずに(-nオプション)、srcかdstのホストIPがxxx.xxx.xxx.xxxかつTCPポート80番

```
$ tcpdump -r sample.pcap host xxx.xxx.xxx.xxx and tcp port 80 -n
```

sample.pcapというpcapファイルを読み込み(-rオプション)、DNSに変換せずに(-nオプション)、srcのホストIPがxxx.xxx.xxx.xxxかつdstのホストIPがyyy.yyy.yyy.yyyかつTCPポート80番

```
$ tcpdump -r sample.pcap ip dst xxx.xxx.xxx.xxx and ip src yyy.yyy.yyy.yyy and tcp port 80 -n
```

### Wireshark

* フィルター例

```
http.request and http contains Root=1-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx   # ALBにおけるアクセスログとキャプチャの関連付け
http.response.code == 502
tcp.flags.reset == 1

ip.addr == 10.0.0.1 && tcp.flags.fin
ip.src == 10.0.0.1 or ip.src == 10.0.0.2
ip.dst == 10.0.0.1
eth.src [0:3] == 00:00:83
tcp.port in {443, 80, 8080}
```

Command Gでパケット番号による検索。

* フィルター詳細 <https://www.wireshark.org/docs/dfref/>

## カーネルソースコード入手

```
# yumdownloader --source kernel
Loaded plugins: auto-update-debuginfo, priorities, update-motd, upgrade-helper
Enabling ius-source repository
Enabling amzn-updates-source repository
Enabling amzn-main-source repository
31 packages excluded due to repository priority protections
kernel-4.9.93-41.60.amzn1.src.rpm                                                                                                                                                     | 136 MB  00:00:03     
# rpm2cpio kernel-4.9.93-41.60.amzn1.src.rpm | cpio -id
1363606 blocks
# tar -xf linux-4.9.93.tar
# ls linux-4.9.93/
arch   certs    CREDITS  Documentation  firmware  include  ipc     Kconfig  lib          Makefile  net     REPORTING-BUGS  scripts   sound  usr
block  COPYING  crypto   drivers        fs        init     Kbuild  kernel   MAINTAINERS  mm        README  samples         security  tools  virt
```

## Yumレポジトリ中のrpmの中のJavaを確認

```
# Get rpm from Yum repository
$ wget <HTTPS URL for rpm in Yum repos>

# Decompress rpm file
$ rpm2cpio aws-hm-client-4.2.0-1.amzn2023.noarch.rpm | cpio -id

# Decompress jar file
$ cd usr/share/aws/hmclient/lib
$ jar xf aws-glue-datacatalog-client-common-4.2.0.jar

# Open .class file with IntelliJ
```

## screen

```
Ctrl+a c : ウィンドウ新規作成
Ctrl+a w : ウィンドウ一覧
Ctrl+a num : ウィンドウ切り替え
Ctrl+a a : ウィンドウ間の行き回
Ctrl+a [ : スクロールモード

Ctrl+a d : セッションをデタッチ
exit: セッションを終了

Ctrl+a S : 画面垂直分割(リージョン分割)
Ctrl+a tab : リージョン切り替え
Ctrl+a x : リージョン削除

作業再開時 : screen -r [Session ID]
指定した名前でセッション新規作成 : screen -S [Session ID]

セッション一覧 : screen -ls
セッション終了 :  screen -XS <Session ID> kill

Copy & Paste : Ctrl + [ ,  Ctrl + ]
```

.screenrcには以下の設定を追加。

```
defscrollback 10000         # スクロールバッファを10000行に設定

# ステータスライン設定
hardstatus alwayslastline
hardstatus string '%{= kG}[ %{G}%H %{g}][%= %{= kw}%?%-Lw%?%{r}(%{W}%n*%f%t%?(%u)%?%{r})%{w}%?%+Lw%?%?%= %{g}][%{B} %m-%d %{W}%c %{g}]'

# マウス操作を有効化
mousetrack on
termcapinfo xterm* ti@:te@
```

* [SCREEN Quick Reference](https://aperiodic.net/screen/quick_reference)

## ディスク容量いっぱい

### 不要ファイルの洗い出し

キャッシュ周りやデプロイ毎に作成されるファイルで、古いものが残っている等の類のものを優先的に見ていく。

```
$ du -sh * | sort -h -r
$ du --max-depth 5 -h * | sort -h -r
```

### yumのキャッシュを確認

* 消すものがさくっとでてこないときにとりあえず

```
du -sh /var/cache/yum
```

前者で十分な事が多いが、容量がいっぱいだと、前者のコマンドも容量不足で実行できないことがある。その場合後者を実行すれば良い。

```
yum clean all
rm -Rf /var/cache/yum
```

* Links
  * [ディスク容量が逼迫しているけど消せるファイルが無い時に試すコマンド](https://blog.grasys.io/post/kyouhei/trying-command-the-diskspace-problemed-but-no-files-can-be-erased/)

## BPF

* References
  * [BPF Performance Tools: Linux System and Application Observability (book)](https://www.brendangregg.com/blog/2019-07-15/bpf-performance-tools-book.html)

## その他

### Unix時間を変換

```
$ date -ud '@1589500800'
2020年  5月 15日 金曜日 00:00:00 UTC
```

MacOSでは以下

```
$ date -ur 1589500800
2020年 5月15日 金曜日 00時00分00秒 UTC
```

### 10進数へ変換

#### 2進数

```
$ echo $((2#101))
```

#### 16進数

```
$ echo $((16#afaf))
```

### ALBで502生成

```
$ sudo iptables -A INPUT -s 192.168.0.10 -p tcp --dport 80 -j REJECT --reject-with tcp-reset
```

## macOS

### ターミナル

* [Macの「ターミナル」のキーボードショートカット](https://support.apple.com/ja-jp/guide/terminal/trmlshtcts/mac)

### VSCode

#### マークダウン表示

* Command + k -> v
  * 画面分割して表示
* Command + Shift -> v
  * 別タブで表示

## 参考資料

* <https://qiita.com/sion\\_cojp/items/04a2aa76a1021fe77079>
* <https://qiita.com/taiyop/items/bfeeb41259cb0d083d88#\\_reference-dfefbef0995e80f8203e>
* <https://qiita.com/ngyuki/items/0edecb8b92fcf189ac2b>
* <http://saosao-0706.hatenablog.com/entry/2016/04/21/101656>
* <https://qiita.com/rsooo/items/42f0902d42bab6ecf175>
* <https://qiita.com/tksnino/items/300e39279ca57d9515f2#\\_reference-f0f5976f3c0d65c5026c>
* <https://qiita.com/hiro-d/items/c3f724cb3d377e21cd91>
* <https://linuxize.com/post/how-to-use-linux-screen/>
* <https://qiita.com/hnishi/items/3190f2901f88e2594a5f>
* <https://unix.stackexchange.com/questions/26685/how-to-split-window-vertically-in-gnu-screen>
* <https://support.apple.com/ja-jp/guide/terminal/trmlshtcts/mac>

## Linux コマンド例 まとめ

* apt-cache
* apt-chrom
* apt-get
* arp
* chkconfig
* createuser
* crontab
* df
* dig
* dmesg
* dmidecode
* dpkg
* expect
* fdisk
* fio
* firewall-cmd
* firewalld
* free
* fsck
* gcc
* gdb
* grep
* hdparm
* host
* ifconfig
* insmod
* iostat
* iotop
* ip
* iptables
* journalctl
* kill
* limit
* lshw
* lsmod
* lspci
* lsusb
* lspci
* lsusb
* ltrace
* lvcreate
* lvextend
* lvreduce
* mkfs
* mkswap
* modprobe
* mount
* mtr
* netstat
* nmtui
* nslookup
* ntpq
* ntpdate
* parted
* pidof
* ping
* postfix
* postqueue
* postsuper
* pstree
* resize2fs
* rmmod
* route
* rsync
* sar
* screen
* script
* service
* smartctl
* snmpwalk
* ss
* strace
* swapon
* sysctl
* systemctl
* tail
* tcpdump
* top
* traceroute
* ulimit
* uptime
* vgcreate
* vgrename
* vgextend
* w
* watch
* yum

### 参照

* コマンドで覚えるLinux 単行本 – 2016/10/12 一戸 英男 (著)
  * <https://www.amazon.co.jp/dp/4802610327>
