🗂

Webアプリケーション開発でよく使う Linux コマンド

2023/07/26に公開

こんにちは。株式会社ペライチ でサーバサイドエンジニアをしている永見です。

多くの Web アプリケーションでは Linux 環境で動いていることでしょう。
私が開発の際、使っているで役立つコマンドを紹介します。

ファイルを作成する

  • 空ファイルを作成するときは...touch

    $ touch text.txt
    
  • サブディレクトリもまとめて作るときは...mkdir -p

    $ mkdir -p dir1/dir2/dir3
    
  • cp で末尾に文字をつけてバックアップするときは...{,}
    ファイル名を 2 回も入力したくないときに。

    $ cp text.txt{,_back}
    
    $ ls
    text.txt    text.txt_back
    

ファイルを一覧表示する

  • ls などファイルパスを指定できる箇所では * , ? と文字指定 [] が使える。
    (ただし正規表現ではないので、複雑な条件なら find やパイプと grep の組み合わせを使ったほうがよいです。)

    $ ls
    file1.txt    file12.txt    file123.txt
    file111.txt  file222.txt   file333.txt
    
    $ ls *2*
    file12.txt   file123.txt   file222.txt
    
    $ ls file?2?.txt
    file123.txt  file222.txt
    
    $ ls file[1-2]*
    file1.txt    file111.txt   file12.txt
    file123.txt  file222.txt
    
  • ツリー形式で表示するときは...tree
    ドキュメントへ添付するときに便利。

    $ tree dir1
    dir1
    └── dir2
        └── dir3
    
  • ディレクトリやファイルを検索するときは...find
    名前だけでなくパーミッションやユーザーなどの属性でも絞り込める。

    $ find . -name '*2*'
    ./file222.txt
    ./dir1/dir2
    ./file12.txt
    ./file123.txt
    
    

文字を探す

  • 文字列を検索するには...grep
    開発中、一番使っている。よく使うオプションを書いてみる。

    • -r : ディレクトリを対象としたときに下位のファイルまで検索する。
    • -i : 大文字小文字を無視する。
    • -I : 大文字の I ( アイ ) 。バイナリファイルを無視する。若干、検索が早くなる。
    • -n : 結果に行数を表示する。
    • -v : 一致する行ではなく、一致しない行を表示する。
    • -C, -B, -A : 後ろに数字をつけて、一致した前後、後、前の行も表示する。
    • -l : ファイル名のみ表示する。
    • -h : ファイル名を表示しない。
    • -E : 正規表現を使う。
    # AND で検索するときは | (パイプ) でつなげる
    $ grep Sample | grep Text
    
    # OR で検索するときは E オプションを使う
    $ grep -E 'Sample|Text' app.log
    

    他にも多くのオプションがあるので、ヘルプをみよう。grep --help

  • 差分を出すには...diff

    $ cat file1.txt
    This is file 1.
    It contains same text.
    
    $ cat file2.txt
    This is file 2.
    It contains same text.
    New line added.
    
    $ diff file1.txt file2.txt
    1c1
    < This is file 1.
    ---
    > This is file 2.
    2a3
    > New line added.
    
    • -y : 左右 2 列に分割して表示する。
    $ diff -y file1.txt file2.txt
    This is file 1.           |       This is file 2.
    It contains same text.            It contains same text.
                              >       New line added.
    
    • diff -r ディレクトリ1 ディレクトリ2 でディレクトリごと差分を表示する
    $ diff -r dir1 dir2
    Only in dir1: file1.txt
    Only in dir2: file3.txt
    

ログを調べる

  • ログを監視するには...tail -F

    $ tail -F logs/debug.log
    
    2023-05-12 09:12:15 info: GET /users/login
    2023-05-12 09:12:16 info: POST /users/login
    

    ログの追加が多くて追えないときは、先の grep を使ってフィルタする

    $ tail -F logs/debug.log | grep -i fatal
    
    2023-05-12 09:18:20 error: Fatal error.
    
  • ログの一部分を取り出す awk

    $ cat logs/debug.log | awk '{print $4,$5}'
    
    GET /users/login
    POST /users/login
    

    実は awk はプログラミング言語だったりする。テキストの加工に広く使える。
    -F オプションで区切り文字を指定して、たとえば CSV の操作もできる。

    $ cat student.csv
    
    Sei,Mei,Age
    Yamada,Tarou,24
    Tanaka,Hanako,23
    
    $ awk -F',' '{print $2" is "$3" years old."}' student.csv
    Mei is Age years old.
    Tarou is 24 years old.
    Hanako is 23 years old.
    

ファイルを判別する

  • ファイル形式を調べるときは...file

    ダウンロードしてきたファイルが壊れているときや、
    ファイル形式が拡張子と一致しているか調べるときなど、ファイル判別してくれる。

    $ file readme.md
    readme.md: Unicode text, UTF-8 text
    
    $ file logo.jpg
    logo.jpg: PNG image data, 979 x 241, 8-bit/color RGB, non-interlaced
    
  • 同じファイルか調べるときは...md5sum

    サイズの大きいテキストファイルや、画像といったバイナリファイルなど、
    同一ファイルか目視で確認しにくい場合はチェックサムを使う。
    1 バイトでも違っていれば異なるハッシュ値になる。

    $ md5sum image1.jpg image1_bak.jpg
    0a9ab36bab4abdfa7cbd22d5d3ad044d image1.jpg
    5718cd7f766cae56a6080a9fa2f08b0a image1_bak.jpg
    
  • 文字エンコードを調べるときは...nkf --guess

    $ nkf --guess utf8.txt
    UTF-8 (LF)
    
    $ nkf --guess sjis.txt
    Shift-JIS (CRLF)
    

    文字エンコードを変換するときにも使う。

    $ cat sjis.txt
    ????????
    
    $ nkf -Lu -w sjis.txt > sjis_conv.txt
    
    $ nkf --guess sjis_conf.txt
    UTF-8 (LF)
    
    $ cat sjis_conv.txt
    あいうえお
    
  • 行数を調べるときは wc -l

    $ wc -l multi.txt
    48 multi.txt
    

外部との通信を確認する

  • 疎通を確認するには ping
    ※ネットワークの設定で ping のプロトコル ICMP のアクセスを禁止されていると通りません。

    $ ping -c5 www.example.com
    
    PING www.example.com (93.184.216.34) 56(84) bytes of data.
    64 bytes from 93.184.216.34 (93.184.216.34): icmp_seq=1 ttl=54 time=118 ms
    64 bytes from 93.184.216.34 (93.184.216.34): icmp_seq=2 ttl=54 time=119 ms
    64 bytes from 93.184.216.34 (93.184.216.34): icmp_seq=3 ttl=54 time=121 ms
    64 bytes from 93.184.216.34 (93.184.216.34): icmp_seq=4 ttl=54 time=120 ms
    64 bytes from 93.184.216.34 (93.184.216.34): icmp_seq=5 ttl=54 time=118 ms
    
    --- www.example.com ping statistics ---
    5 packets transmitted, 5 received, 0% packet loss, time 4007ms
    rtt min/avg/max/mdev = 117.567/119.307/121.187/1.360 ms
    
  • ドメインの DNS 情報を調べるときは dig
    同じ用途のコマンドとして nslookup があるのでお好みで。

    $ dig A +short peraichi.com
    13.225.165.43
    13.225.165.100
    13.225.165.33
    13.225.165.6
    
  • IP アドレスの登録情報を確認するときは whois
    下記の例だと AWS を使っているのが分かる。
    クラウドだったり、whois 公開代行もあるので、あくまで参考程度に...。

    $ whois 13.225.165.6 | grep -C5 Country
    
    OrgId:          AMAZON-4
    Address:        1918 8th Ave
    City:           SEATTLE
    StateProv:      WA
    PostalCode:     98101-1244
    Country:        US RegDate:        1995-01-23 Updated:        2022-09-30
    Ref:            https://rdap.arin.net/registry/entity/AMAZON-4
    
  • HTTP で送受信を確認するには... curl
    これも同じ用途のコマンドとして wget があるのでお好みで。

    # POST 送信
    $ curl -X POST -d "name=Yamada" https://example.com/users/edit
    
    # リクエストヘッダーをつける
    $ curl -H "Cookie: SID=5758ac271edaa69;" https://example.com/my_page
    
    $ レスポンスヘッダーも表示する
    $ curl -i https://example.com
    
    HTTP/2 200
    server: nginx
    date: Mon, 04 Jul 2023 12:34:56 GMT
    content-type: text/html; charset=UTF-8
    content-length: 1234
    age: 3600
    via: 1.1 varnish
    accept-ranges: bytes
    
    <!DOCTYPE html>
    <html>
      <head>
        <title>Example Domain</title>
      </head>
      <body>
        Hello World
      </body>
    </html>
    

    HTTP リクエストができることは、基本できる。
    アプリケーションで書いた通信プログラムが動かないとき、
    実際にサーバにログインして curl で確かめてみると原因の切り分けがしやすい。

  • 接続しているサーバのグローバル IP を確認するには... curl http://httpbin.org/ip
    通信先が IP 制限をかけているときなどに確認しておく。

    $ curl http://httpbin.org/ip
    {
      "origin": "123.123.123.123"
    }
    

    (※ https://httpbin.org は他にも用意されているので、一度見に行くと良いです。)

負荷状況を調べる

  • リアルタイムにプロセスをモニタ表示するには...top

    負荷が高いとき load average の部分を見る。
    これを CPU のコア数で割って、1 以下なら安全圏内、3~5 以上なら負荷が高め、
    それを超える状態が続いている場合は、何かしら起きている可能性がある...

    $ top
    
    top - 17:15:20 up  3:06,  2 users,  load average: 0.47, 0.46, 0.21
    Tasks: 224 total,   1 running, 223 sleeping,   0 stopped,   0 zombie
    %Cpu(s): 51.3 us,  2.3 sy,  0.0 ni, 46.3 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
    MiB Mem :   7926.7 total,   3127.4 free,   1602.6 used,   3196.7 buff/cache
    MiB Swap:   4096.0 total,   4096.0 free,      0.0 used.   5901.7 avail Mem 
    
    PID  USER     PR NI VIRT    RES    SHR    S %CPU  %MEM TIME+   COMMAND
    1773 develop  20 0  4691208 718804 232116 S 103.7 8.9  7:19.91 gnome-shell
    2710 develop  20 0  694208  83888  66176  S 2.0   1.0  0:13.56 gnome-terminal
    1140 mysql    20 0  1790068 390016 33136  S 0.7   4.8  2:19.95 mysqld
    748  systemd+ 20 0  15024   3788   3044   S 0.3   0.0  0:30.09 systemd-oomd
    2054 develop  20 0  240028  12192  10656  S 0.3   0.2  0:00.56 ibus-engine-moz
    1    root     20 0  103308  12256  7552   S 0.0   0.2  0:03.20 systemd
    :
    
  • サーバのメモリの空き状況をみるときは... free -h

    最新の OS バージョンなら、使用可能なメモリサイズとして available を表示してくれる。
    (便利になった!)

    $ free -h
               total        used        free      shared  buff/cache   available
    Mem:       7.7Gi       1.9Gi       1.9Gi       339Mi       4.0Gi       5.3Gi
    Swap:      4.0Gi          0B       4.0Gi
    

    従来の free コマンドの出力では -/+ buffers/cache: の free の部分をみる。

               total       used       free     shared    buffers     cached
    Mem:        7.8G       3.8G       1.8G       182M       2.2G       3.6G
    -/+ buffers/cache:     397M       7.4G
    Swap:       2.0G         0B       2.0G
    
  • サーバのディスク領域の使用状況をみるときは...df -h

    $ df -h
    Filesystem                         Size  Used Avail Use% Mounted on
    tmpfs                              793M  1.9M  791M   1% /run
    /dev/mapper/ubuntu--vg-ubuntu--lv   60G   37G   21G  64% /
    tmpfs                              3.9G   66M  3.9G   2% /dev/shm
    tmpfs                              5.0M  4.0K  5.0M   1% /run/lock
    /dev/vda2                          2.0G  263M  1.6G  15% /boot
    /dev/vda1                          1.1G  6.4M  1.1G   1% /boot/efi
    tmpfs                              793M  128K  793M   1% /run/user/1000
    
  • どのディレクトリが容量を大きくとっているか調べるときは... du -h --max-depth=1
    --max-depth=1 オプションで指定のディレクトリ直下のみにした方が特定しやすい。

    $ du -h --max-depth=1 /var/log
    8.0K    /var/log/nginx
    585M    /var/log/journal
    36K     /var/log/unattended-upgrades
    32K     /var/log/mysql
    236K    /var/log/apt
    4.0K    /var/log/dist-upgrade
    4.0K    /var/log/speech-dispatcher
    968K    /var/log/installer
    4.0K    /var/log/private
    8.0K    /var/log/hp
    4.0K    /var/log/openvpn
    4.0K    /var/log/sssd
    4.0K    /var/log/landscape
    64K     /var/log/cups
    4.0K    /var/log/gdm3
    592M    /var/log
    

出力を加工する

  • 出力を次のコマンドに渡すには...xargs
    パイプでつなげて次のコマンドの引数にできる。
    下記は空のディレクトリに .keep ファイルを設置する例。

    $ tree -a dir1
    dir1
    ├── dir2
    │   └── .keep
    ├── dir3
    └── dir4
    
    $ find dir1 -type d -empty
    dir1/dir3
    dir1/dir4
    
    $ find dir1 -type d -empty | xargs -I{} touch {}/.keep
    
    $ tree -a dir1
    dir1
    ├── dir2
    │   └── .keep
    ├── dir3
    │   └── .keep
    └── dir4
        └── .keep
    
  • 出力をソートするには...sort -h
    -h を付けると人間の感覚に近い形でソートしてくれる。
    -r で逆順にできる。

    $ ls -lh
    total 4.0K
    -rw-r--r-- 1 user user  10K Jul  4 10:00 file1.txt
    -rw-r--r-- 1 user user  1M  Jul  4 09:30 file2.txt
    -rw-r--r-- 1 user user 100  Jul  4 09:15 file3.txt
    -rw-r--r-- 1 user user 5K   Jul  4 09:45 file4.txt
    
    $ ls -lh | sort -h
    -rw-r--r-- 1 user user 100  Jul  4 09:15 file3.txt
    -rw-r--r-- 1 user user 5K   Jul  4 09:45 file4.txt
    -rw-r--r-- 1 user user 10K  Jul  4 10:00 file1.txt
    -rw-r--r-- 1 user user 1M   Jul  4 09:30 file2.txt
    
  • JSON 出力を整形するには...jq
    API から返ってきた JSON 形式のレスポンスは、そのままでは読みづらい。
    jq コマンドで整形して見よう。

    $ curl https://example.com/api/users/1
    {"id":1,"name":"John","age":30,"city":"Tokyo"}
    
    $ curl https://example.com/api/users/1 | jq
    {
      "id" : 1,
      "name": "John",
      "age": 30,
      "city": "New York"
    }
    

    抽出や加工も可能だ。

    $ curl https://example.com/api/users/1 | jq '.name'
    "John"
    
    $ curl https://example.com/api/users/1 | jq -r '.result = .name + " is " + (.age|tostring) + " years old." | .result'
    John is 30 years old.
    

その他

  • コマンドを繰り返し実行したいときは...watch
    編集画面と実行画面の間を行き来しなくてもすむので、ユニットテストやバッチの実装で使うと捗る。

    $ watch -n 10 ./vendor/bin/phpunit tests/TestCase/Model/UserTableTest.php --filter="Case_1"
    Every 10.0s: ./vendor/bin/phpunit tests/TestCase/Model/...
    
    PHPUnit 9.5.10 by Sebastian Bergmann and contributors.
    
    F                                     1 / 1 (100%)
    
    Time: 00:02.345, Memory: 8.00 MB
    
    There were 1 failures:
    
    1) Failed Test Case 1
       Assertion failed.
    
  • コマンドの実行時間を測りたいときは...time

    $ time sh example_command.sh
    
    real    1m3.819s
    user    1m2.642s
    sys     1m0.719s
    
  • 接続切れによるコマンド停止を防ぎたいときは...screen
    SSH ログインの接続が切れると、実行中のコマンドは停止してしまう場合がある。
    この screen を使うと SSH 接続が切れても、実行を継続させることができる。

    # セッション開始
    $ screen
    
    # 復帰
    $ screen -r
    
    # セッションの一覧表示
    $ screen -ls
    

いかがでしたでしょうか。

いろいろと書き連ねてみましたが、これでも一部の機能です。
詳細な使い方やさまざまな操作については、各コマンドのドキュメントを参照した方が良いでしょう。
(特に grepfindcurldigawkjq あたりは。)

少しでもお役に立てれば幸いです。
読んでいただきありがとうございました。

採用情報

現在エンジニア募集しています!

▼ 採用ページ
https://recruit.peraichi.co.jp/

▼ 選考をご希望の方はこちら(募集職種一覧)
https://hrmos.co/pages/peraichi/jobs?utm_source=techblog&utm_medium=referral&utm_campaign=article-01gzw86zydc386477bk9644wtn

▼ まずはカジュアル面談をご希望の方はこちら
https://hrmos.co/pages/peraichi/jobs/0000029?utm_source=techblog&utm_medium=referral&utm_campaign=article-01gzw86zydc386477bk9644wtn

募集中の職種についてご興味がある方は、お気軽にお申し込みください(CTO がお会いします)

Discussion