Linuxのシェルとカーネルの仕組みを理解する

シェルとカーネルは、Linuxシステムの根幹を成す重要な概念です。この2つの関係を正確に理解することで、表面的なコマンド操作から、システム内部の動きを把握できる真のエンジニアへと成長できます。

この記事では、シェルとカーネルの基本的な仕組みから、両者がどう連携して動作するのか、そして実務で押さえておくべきポイントまで、現場で死なないための知識を体系的に解説します。初学者の方も、中堅手前の方も、ぜひこの機会に本質的な理解を深めてください。

目次

カーネルとは何か

カーネル(Kernel)は、Linuxシステムの中核(コア)を成すソフトウェアです。オペレーティングシステムの心臓部とも言える存在で、ハードウェアとアプリケーションの橋渡しをする重要な役割を担っています。

カーネルの主要な役割

カーネルには、大きく分けて以下の4つの重要な役割があります。

1. ハードウェア管理

CPU、メモリ、ディスク、ネットワークカードなどの物理的なハードウェアを直接制御します。アプリケーションは、ハードウェアに直接アクセスすることはできません。必ずカーネルを経由する必要があります。

これにより、複数のアプリケーションが同時にハードウェアを使っても、互いに干渉せず安全に動作できます。

2. プロセス管理

複数のプログラムを同時に実行するために、プロセスのスケジューリング(どのプロセスにCPU時間を割り当てるか)を行います。

$ ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.1 169416 13872 ?        Ss   10:00   0:01 /sbin/init
iwata     1234  0.5  0.3 234512 28904 pts/0    Ss   10:15   0:12 bash
iwata     5678  2.1  1.5 512384 124516 pts/0   Sl+  11:00   5:23 python app.py

このように、多数のプロセスが同時に動作していますが、カーネルが適切にCPU時間を配分しています。

3. メモリ管理

物理メモリ(RAM)を効率的に管理し、各プロセスに必要なメモリ空間を割り当てます。また、仮想メモリの仕組みを提供し、物理メモリ以上のメモリ空間をプロセスに見せることができます。

$ free -h
              total        used        free      shared  buff/cache   available
Mem:           15Gi       3.2Gi       8.1Gi       256Mi       4.0Gi        11Gi
Swap:         2.0Gi          0B       2.0Gi

メモリが不足したときは、ディスク上のスワップ領域を使って仮想的にメモリを拡張します。

4. ファイルシステム管理

ディスク上のデータをファイルとディレクトリという形で管理し、読み書きを制御します。ext4、XFS、Btrfsなど、さまざまなファイルシステムをサポートします。

$ df -hT
Filesystem     Type      Size  Used Avail Use% Mounted on
/dev/sda1      ext4       50G   20G   28G  42% /
/dev/sdb1      xfs       100G   45G   55G  45% /data

カーネルは、これらのファイルシステムの違いを吸収し、アプリケーションに統一的なインターフェースを提供します。

カーネル空間とユーザー空間

Linuxシステムは、カーネル空間(Kernel Space)ユーザー空間(User Space)という2つの領域に分かれています。

領域説明実行されるもの権限
カーネル空間システムの中核領域カーネル本体、デバイスドライバ完全な権限
ユーザー空間アプリケーションが動作する領域シェル、アプリケーション、デーモン制限された権限

ユーザー空間で動作するプログラムは、ハードウェアに直接アクセスできません。システムコールという仕組みを使って、カーネルに処理を依頼する必要があります。

システムコール – カーネルへの窓口

システムコール(System Call)は、ユーザー空間からカーネルの機能を呼び出すためのインターフェースです。

たとえば、ファイルを開くopen()、データを読むread()、プロセスを作成するfork()などは、すべてシステムコールです。

$ strace ls /tmp
execve("/usr/bin/ls", ["ls", "/tmp"], 0x7ffd1234abcd /* 24 vars */) = 0
brk(NULL)                               = 0x55abcd123000
openat(AT_FDCWD, "/tmp", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = 3
getdents64(3, /* 15 entries */, 32768)  = 480
write(1, "file1.txt\nfile2.txt\n", 20)  = 20
close(3)                                = 0
exit_group(0)                           = ?

straceコマンドを使うと、プログラムがどのシステムコールを呼び出しているかを確認できます。この例では、openat()でディレクトリを開き、getdents64()でファイル一覧を取得し、write()で標準出力に書き込んでいます。

カーネルのバージョン確認

現在動作しているカーネルのバージョンを確認するには、unameコマンドを使います。

$ uname -r
5.15.0-91-generic

この出力は、カーネルバージョン5.15.0、パッチレベル91、ビルド種別genericを意味します。

より詳細な情報を見るには、以下のコマンドを使います。

$ uname -a
Linux server 5.15.0-91-generic #101-Ubuntu SMP Tue Nov 14 13:30:08 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux

カーネルのバージョンは、セキュリティパッチやバグフィックスの適用状況を確認するために重要です。古いカーネルを使い続けると、既知の脆弱性を抱えることになります。

シェルとは何か

シェル(Shell)は、ユーザーとカーネルの間に位置する対話的なインターフェースです。貝殻(shell)がカーネル(核)を包み込むように、ユーザーからカーネルを保護し、使いやすくする役割を果たします。

シェルの主要な役割

シェルには以下のような重要な役割があります。

1. コマンドの解釈と実行

ユーザーが入力したコマンドを解釈し、適切なプログラムを起動します。

$ ls -la /etc

このコマンドを入力すると、シェルは以下の処理を行います。

  1. コマンドライン全体を解析する
  2. lsというコマンドを/usr/bin/lsから探す
  3. 引数-la/etcを渡してプログラムを実行する
  4. プログラムの出力を画面に表示する

2. 環境変数の管理

プログラムの動作に影響を与える環境変数を管理します。

$ echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin

PATH環境変数は、シェルがコマンドを探す際に検索するディレクトリのリストです。

3. スクリプトの実行

複数のコマンドをまとめたスクリプトを実行できます。

$ cat script.sh
#!/bin/bash
echo "Starting backup..."
tar -czf backup.tar.gz /data
echo "Backup completed!"
$ bash script.sh
Starting backup...
Backup completed!

4. リダイレクトとパイプ

コマンドの入出力を制御する機能を提供します。

$ ls -l > file_list.txt
$ cat file1.txt | grep "error" | wc -l

これらの機能は、シェルが提供する強力な機能です。

主要なシェルの種類

Linuxには複数のシェルが存在します。それぞれ特徴が異なります。

シェル説明パス
bashBourne Again Shell。最も一般的なシェル/bin/bash
sh元祖シェル(現在はbashへのリンク)/bin/sh
zshZ Shell。高機能で補完が強力/bin/zsh
fishFriendly Interactive Shell。初心者向け/usr/bin/fish
dashDebian Almquist Shell。軽量で高速/bin/dash

現在使用中のシェルを確認するには、以下のコマンドを使います。

$ echo $SHELL
/bin/bash

この出力は、現在のログインシェルがbashであることを示しています。

ログインシェルとインタラクティブシェルの違い

シェルには、動作モードによって2つの分類があります。

ログインシェル

ユーザーがシステムにログインしたときに起動されるシェルです。

$ ssh user@server.example.com

SSHでログインすると、ログインシェルが起動します。ログインシェルは、以下のような初期化ファイルを読み込みます。

  • /etc/profile
  • ~/.bash_profile
  • ~/.bash_login
  • ~/.profile

インタラクティブシェル(非ログインシェル)

すでにログインした状態で、新しくシェルを起動した場合です。

$ bash

このようにシェルを起動すると、インタラクティブシェルが起動します。この場合、以下のファイルを読み込みます。

  • ~/.bashrc

シェルの初期化ファイルの読み込み順序

bashの場合、ログインシェルとして起動したときの読み込み順序は以下の通りです。

  1. /etc/profile(システム全体の設定)
  2. ~/.bash_profile(個人設定、最優先)
  3. ~/.bash_login.bash_profileがない場合)
  4. ~/.profile(上記2つがない場合)

一方、非ログインシェルの場合:

  1. /etc/bash.bashrc(システム全体の設定)
  2. ~/.bashrc(個人設定)

現場での実務ポイント: 環境変数や関数の設定は~/.bashrcに書き、~/.bash_profileから~/.bashrcを読み込むようにするのが一般的です。

$ cat ~/.bash_profile
if [ -f ~/.bashrc ]; then
    . ~/.bashrc
fi

こうすることで、ログインシェルでも非ログインシェルでも同じ設定が適用されます。

シェルとカーネルの連携の仕組み

ここからは、シェルとカーネルがどのように連携してコマンドを実行するのか、内部の仕組みを見ていきます。

コマンド実行の流れ

ユーザーがコマンドを入力してから実行されるまでの流れは、以下のようになっています。

$ ls /etc

ステップ1: シェルがコマンドを解析

シェルは、入力された文字列ls /etcを解析し、以下の要素に分解します。

  • コマンド名: ls
  • 引数: /etc

ステップ2: コマンドの種類を判定

シェルは、ls内部コマンド外部コマンドかを判定します。

  • 内部コマンド(ビルトインコマンド): シェル自身が実装しているコマンド(cd, echo, exportなど)
  • 外部コマンド: 独立した実行ファイル(ls, cat, grepなど)

lsは外部コマンドなので、次のステップに進みます。

ステップ3: 実行ファイルの検索

シェルは、PATH環境変数に設定されたディレクトリを順番に探し、lsという実行ファイルを見つけます。

$ which ls
/usr/bin/ls

ステップ4: 新しいプロセスの作成(fork)

シェルは、fork()というシステムコールを使って、自分自身のコピー(子プロセス)を作成します。

この時点では、親プロセス(シェル)と子プロセスはまったく同じ状態です。

ステップ5: プログラムの実行(exec)

子プロセスは、exec()というシステムコールを使って、自分自身を/usr/bin/lsプログラムに置き換えます

これにより、子プロセスはlsとして動作を開始します。

ステップ6: カーネルが実行を制御

カーネルは、lsプロセスにCPU時間を割り当て、必要なシステムコールを処理します。lsは、ディレクトリの内容を読み取るためにopenat()getdents64()などのシステムコールを発行します。

ステップ7: 結果の出力

lsプログラムは、ファイル一覧を標準出力に書き込みます。標準出力は、通常はターミナル画面に接続されているため、結果が画面に表示されます。

ステップ8: プロセスの終了と待機

lsプログラムが処理を終えると、exit()システムコールを呼び出してプロセスを終了します。親プロセス(シェル)は、wait()システムコールで子プロセスの終了を待ち、制御を取り戻します。

ユーザー入力
↓
┌───────────────┐
│ シェル         │ ← ユーザー空間
│ (bash)        │
└───────────────┘
↓ fork() / exec()
┌───────────────┐
│ lsプロセス     │
└───────────────┘
↓ システムコール (openat, getdents64, write)
┌───────────────┐
│ カーネル       │ ← カーネル空間
│ (Linux Kernel)│
└───────────────┘
↓ ハードウェア操作
┌───────────────┐
│ ハードウェア   │
│ (ディスク等)   │
└───────────────┘

内部コマンドと外部コマンドの違い

前述の通り、シェルのコマンドには2種類あります。

内部コマンド(ビルトインコマンド)

シェル自身が実装しているコマンドです。新しいプロセスを作成せずに、シェル内部で処理されます。

$ type cd
cd is a shell builtin

cdは内部コマンドなので、which cdでは実行ファイルが見つかりません。

内部コマンドの主な例:

  • cd: ディレクトリ移動
  • echo: 文字列出力
  • export: 環境変数の設定
  • alias: エイリアスの設定
  • source.): ファイルの読み込み

外部コマンド

独立した実行ファイルとして存在するコマンドです。実行時に新しいプロセスが作成されます。

$ type ls
ls is /usr/bin/ls

外部コマンドの主な例:

  • ls: ファイル一覧表示
  • cat: ファイル内容表示
  • grep: 文字列検索
  • find: ファイル検索

なぜcdは内部コマンドなのか

cdが内部コマンドである理由は、プロセスは自分の親プロセスのカレントディレクトリを変更できないからです。

もしcdが外部コマンドだとすると、新しいプロセスが作成され、そのプロセスのカレントディレクトリが変わるだけで、シェル自体のカレントディレクトリは変わりません。

そのため、cdはシェル自身が処理する必要があります。

プロセスの親子関係

シェルとコマンドの関係を理解するには、プロセスの親子関係を知る必要があります。

$ pstree -p $$
bash(1234)───pstree(5678)

$$は現在のシェルのプロセスID(PID)を表す特殊変数です。この例では、bash(PID 1234)が親プロセスで、pstree(PID 5678)が子プロセスです。

複数のコマンドを実行すると、それぞれが独立した子プロセスになります。

$ sleep 100 &
$ sleep 200 &
$ pstree -p $$
bash(1234)─┬─sleep(5680)
           ├─sleep(5681)
           └─pstree(5682)

&を付けるとバックグラウンドで実行されるため、シェルはすぐに制御を取り戻します。

シェルの内部動作を理解する

ここからは、シェルがどのように動作しているのか、より深く掘り下げていきます。

シェルのプロンプトとPS1変数

シェルのプロンプト($#の前に表示される文字列)は、PS1という環境変数で制御されています。

$ echo $PS1
\u@\h:\w\$

これは特殊な記号を含む文字列で、以下のように解釈されます。

記号意味
\uユーザー名
\hホスト名
\wカレントディレクトリ
\$$(rootなら#

プロンプトをカスタマイズすることもできます。

$ export PS1="[\t] \u@\h:\w\$ "
[11:30:45] iwata@server:~/project$

時刻(\t)が追加されました。

シェルの終了ステータス

コマンドを実行すると、終了ステータス(Exit Status)という数値が返されます。

  • 0: 成功
  • 1-255: エラー(値によってエラーの種類が異なる)

終了ステータスは、$?という特殊変数で確認できます。

$ ls /etc
(ファイル一覧が表示される)
$ echo $?
0

成功したので、終了ステータスは0です。

$ ls /nonexistent
ls: cannot access '/nonexistent': No such file or directory
$ echo $?
2

エラーが発生したので、終了ステータスは2(ファイルが存在しない)です。

終了ステータスは、シェルスクリプトで条件分岐を行う際に重要です。

$ if ls /etc > /dev/null 2>&1; then
    echo "Directory exists"
else
    echo "Directory does not exist"
fi
Directory exists

サブシェルと環境変数の継承

シェルから別のシェルやコマンドを起動すると、サブシェル(子プロセス)が作成されます。

環境変数には、エクスポートされた変数ローカル変数の2種類があります。

$ LOCAL_VAR="local"
$ export EXPORT_VAR="exported"

サブシェルを起動してみます。

$ bash -c 'echo $LOCAL_VAR'
(何も表示されない)
$ bash -c 'echo $EXPORT_VAR'
exported

エクスポートされた変数だけが、子プロセスに引き継がれます。これは、環境変数の基本的な動作です。

シェルのジョブ制御

シェルには、ジョブ制御という機能があり、複数のプロセスを管理できます。

$ sleep 1000 &
[1] 5690

&を付けるとバックグラウンドで実行されます。[1]はジョブ番号、5690はプロセスIDです。

現在のジョブ一覧を確認するには:

$ jobs
[1]+  Running                 sleep 1000 &

バックグラウンドジョブをフォアグラウンドに戻すには:

$ fg %1

Ctrl+Zでプロセスを一時停止できます。

$ sleep 1000
^Z
[1]+  Stopped                 sleep 1000

停止したジョブをバックグラウンドで再開するには:

$ bg %1
[1]+ sleep 1000 &

カーネルモジュールとデバイスドライバ

カーネルの機能を拡張するために、カーネルモジュールという仕組みがあります。

カーネルモジュールとは

カーネルモジュールは、カーネルに動的に追加・削除できる機能の塊です。主にデバイスドライバやファイルシステムの実装に使われます。

現在読み込まれているモジュールを確認するには:

$ lsmod
Module                  Size  Used by
nvidia_drm             69632  0
nvidia_modeset       1224704  1 nvidia_drm
nvidia              56610816  1 nvidia_modeset
ext4                  614400  2

各列の意味は以下の通りです。

  • Module: モジュール名
  • Size: メモリ使用量(バイト)
  • Used by: このモジュールを使用している他のモジュール

モジュールの情報を確認

特定のモジュールの詳細情報を見るには:

$ modinfo ext4
filename:       /lib/modules/5.15.0-91-generic/kernel/fs/ext4/ext4.ko
license:        GPL
description:    Fourth Extended Filesystem
author:         Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o

モジュールの手動ロードとアンロード

モジュールを手動でロードするには:

$ sudo modprobe module_name

アンロードするには:

$ sudo modprobe -r module_name

現場での注意点:
使用中のモジュールはアンロードできません。また、本番環境でモジュールを安易にアンロード・ロードすると、システムが不安定になる可能性があるため、慎重に行ってください。

/procと/sys – カーネル情報へのアクセス

カーネルの状態を確認したり、動作を調整したりするために、/proc/sysという特殊なディレクトリが用意されています。

/proc – プロセスとシステム情報

/procは、プロセスやシステムの情報を提供する仮想ファイルシステムです。実際にディスク上にファイルが存在するわけではなく、カーネルが動的に生成しています。

$ ls /proc
1  100  1234  2  3  cpuinfo  meminfo  uptime  version  ...

数字のディレクトリは、各プロセスのPIDを表しています。

CPU情報の確認

$ cat /proc/cpuinfo | head -20
processor       : 0
vendor_id       : GenuineIntel
cpu family      : 6
model           : 142
model name      : Intel(R) Core(TM) i7-8550U CPU @ 1.80GHz
stepping        : 10
microcode       : 0xf0
cpu MHz         : 1992.000
cache size      : 8192 KB
...

メモリ情報の確認

$ cat /proc/meminfo | head -10
MemTotal:       16312164 kB
MemFree:         8456728 kB
MemAvailable:   12234560 kB
Buffers:          456832 kB
Cached:          3987456 kB
SwapCached:            0 kB
Active:          5123456 kB
Inactive:        2345678 kB

特定プロセスの情報

プロセスIDが1234のプロセス情報を見るには:

$ ls /proc/1234
cmdline  environ  exe  fd  maps  stat  status  ...

コマンドラインを確認:

$ cat /proc/1234/cmdline

プロセスが開いているファイルディスクリプタを確認:

$ ls -l /proc/1234/fd
lrwx------ 1 iwata iwata 64 Jan 31 12:00 0 -> /dev/pts/0
lrwx------ 1 iwata iwata 64 Jan 31 12:00 1 -> /dev/pts/0
lrwx------ 1 iwata iwata 64 Jan 31 12:00 2 -> /dev/pts/0
lr-x------ 1 iwata iwata 64 Jan 31 12:05 3 -> /var/log/app.log

/sys – デバイスとカーネル設定

/sysは、デバイスやカーネルの設定にアクセスするための仮想ファイルシステムです。

$ ls /sys
block  bus  class  dev  devices  firmware  kernel  module  power

たとえば、ネットワークインターフェースの情報を見るには:

$ cat /sys/class/net/eth0/speed
1000

リンク速度が1000Mbps(1Gbps)であることがわかります。

実務の落とし穴

ここからは、シェルとカーネルに関する実務でよく遭遇するトラブルと、その対処法を紹介します。

1. シェルスクリプトのシバン(shebang)を間違える

シェルスクリプトの1行目には、シバン(shebang)という特殊な記述が必要です。

$ cat script.sh
#!/bin/bash
echo "Hello, World!"

#!/bin/bashがシバンです。これにより、このスクリプトをbashで実行することをカーネルに指示します。

よくある間違い

#/bin/bash
echo "Hello"

!が抜けています。この場合、シェルはシバンとして認識せず、デフォルトのシェル(通常は/bin/sh)で実行されます。

もう一つの間違い

#!/bin/sh

shは古いシェルで、bashの拡張機能が使えません。現代のスクリプトでは、明示的に#!/bin/bashを使うべきです。

2. 環境変数のエクスポートを忘れる

スクリプト内で設定した変数が、サブプロセスに引き継がれないケースです。

$ cat test.sh
#!/bin/bash
MY_VAR="test"
bash -c 'echo $MY_VAR'
$ bash test.sh
(何も表示されない)

MY_VARはエクスポートされていないため、サブシェルには引き継がれません。

正しい方法

#!/bin/bash
export MY_VAR="test"
bash -c 'echo $MY_VAR'
$ bash test.sh
test

3. カレントディレクトリの.を忘れる

自作スクリプトを実行しようとして、コマンドが見つからないエラーが出るケースです。

$ chmod +x script.sh
$ script.sh
script.sh: command not found

これは、カレントディレクトリ(.)がPATHに含まれていないためです。

正しい方法

$ ./script.sh

または、フルパスで指定します。

$ /home/iwata/script.sh

セキュリティ上の理由から、カレントディレクトリをPATHに含めることは推奨されません

4. システムコールの失敗を確認しない

スクリプト内でコマンドが失敗しても、そのまま処理が続行されてしまうケースです。

#!/bin/bash
cd /nonexistent
rm -rf *

このスクリプトは極めて危険です。cdが失敗しても、rm -rf *が実行され、意図しないディレクトリのファイルが削除される可能性があります。

正しい方法

#!/bin/bash
set -e  # エラーが発生したら即座に終了
cd /nonexistent
rm -rf *

または、個別にエラーチェックを行います。

#!/bin/bash
cd /nonexistent || { echo "Failed to change directory"; exit 1; }
rm -rf *

5. プロセスが残り続ける(ゾンビプロセス)

子プロセスが終了したのに、親プロセスがwait()を呼ばないと、ゾンビプロセスになります。

$ ps aux | grep Z
iwata     5690  0.0  0.0      0     0 ?        Z    12:00   0:00 [defunct]

STAT列にZが付いているのがゾンビプロセスです。

ゾンビプロセス自体は害はありませんが、大量に発生するとプロセステーブルを圧迫します。

対処法

親プロセスを修正して、適切にwait()を呼ぶようにします。一時的な対処としては、親プロセスを再起動することでゾンビプロセスは消えます。

6. /procや/sysのファイルを誤って削除しようとする

/proc/sysは仮想ファイルシステムなので、実際にはディスク上にファイルが存在しません。

$ rm /proc/cpuinfo
rm: cannot remove '/proc/cpuinfo': Operation not permitted

削除はできませんが、試すこと自体が無意味です。

7. カーネルパラメータを恒久的に変更していない

/proc/sys配下のファイルを直接編集しても、再起動すると設定が失われます

$ echo 1 > /proc/sys/net/ipv4/ip_forward

この設定は、再起動すると元に戻ります。

正しい方法

/etc/sysctl.confまたは/etc/sysctl.d/配下のファイルに設定を記述します。

$ sudo vim /etc/sysctl.d/99-custom.conf
net.ipv4.ip_forward = 1

設定を即座に反映するには:

$ sudo sysctl -p /etc/sysctl.d/99-custom.conf

8. シェルとターミナルの違いを理解していない

「シェル」と「ターミナル」は異なる概念ですが、混同されることがあります。

  • ターミナル(端末エミュレータ): 文字を表示する画面(gnome-terminal、iTerm2など)
  • シェル: コマンドを解釈して実行するプログラム(bash、zshなど)

ターミナルはあくまで入出力のインターフェースで、実際のコマンド処理はシェルが行います。

まとめ

この記事では、Linuxシステムの根幹を成すシェルとカーネルの仕組みについて解説しました。重要なポイントを以下にまとめます。

カーネルの役割

  • ハードウェア管理: CPU、メモリ、ディスク、ネットワークを制御
  • プロセス管理: 複数プロセスのスケジューリング
  • メモリ管理: 物理メモリと仮想メモリの管理
  • ファイルシステム管理: ディスク上のデータを管理

カーネルはカーネル空間で動作し、完全な権限を持ちます。

シェルの役割

  • コマンドの解釈と実行: ユーザー入力を処理
  • 環境変数の管理: プログラムの動作環境を制御
  • スクリプトの実行: 複数コマンドの自動化
  • リダイレクトとパイプ: 入出力の制御

シェルはユーザー空間で動作し、カーネルに対してシステムコールを発行します。

コマンド実行の流れ

  1. シェルがコマンドを解析
  2. fork()で子プロセスを作成
  3. exec()で実行ファイルに置き換え
  4. カーネルがプロセスを実行
  5. プロセスが終了し、シェルに制御が戻る

内部コマンドと外部コマンド

  • 内部コマンド: シェル自身が処理(cd, echo, exportなど)
  • 外部コマンド: 独立した実行ファイル(ls, cat, grepなど)

重要なファイルとディレクトリ

パス説明
/procプロセスとシステム情報を提供する仮想ファイルシステム
/sysデバイスとカーネル設定にアクセスする仮想ファイルシステム
~/.bashrc非ログインシェルの初期化ファイル
~/.bash_profileログインシェルの初期化ファイル
/etc/sysctl.confカーネルパラメータの恒久的な設定

実務で覚えておくべきこと

  • シェルスクリプトには必ず#!/bin/bashのシバンを付ける
  • 環境変数をサブプロセスに引き継ぐにはexportが必要
  • エラーが発生したら処理を止めるため、set -eを使う
  • カーネルパラメータを恒久的に変更するには/etc/sysctl.confを編集
  • /proc/sysはディスク上に実在しない仮想ファイルシステム

シェルとカーネルの関係を理解することは、Linuxシステムの本質を理解する第一歩です。

表面的なコマンド操作だけでなく、その裏側で何が起きているのかを意識することで、トラブルシューティングの精度が格段に上がります。パフォーマンスチューニングを行う際も、どのレイヤーを最適化すべきかが明確になります。

この記事で学んだ知識を実際に手を動かして試し、システムの内部動作を体感してください。straceでシステムコールを観察したり、/proc配下のファイルを読んだり、シェルスクリプトを書いたりすることで、理解がより深まります。