Open60

Linux 『新しいLinuxの教科書』

mabomabo

ディストリビューション

OSの核となるカーネルに基本的なコマンド群やアプリケーションなどを加えて、ユーザーがそのまま利用できるようにパッケージングしたもの。

種類

①Red Hat系
Red Hat Enterprise Linux, CentOS Stream, Fedora

②Debian系
Debian GNU / Linux, Ubuntu

全体像

https://prefapp.es/de-los-namespaces-en-linux/ より画像引用

mabomabo

仮想化


https://clouddirect.jp.fujitsu.com/service/navi-beginner-virtualization より画像引用

仮想化とは、サーバーなどのハードウエアリソース(CPU、メモリ、ディスクなど)を抽象化し、物理的な制限にとらわれず、ソフトウエア的に統合・分割できるようにする技術

サーバ仮想化とは、1台の物理サーバ上に複数のOSを動作させる技術
本物の(物理的な)サーバーではないが、ソフトウエアによって実質的に本物と同じように扱えるサーバー

現代のように仮想化技術が普及していなかった頃は、サーバーは用途ごとに専用のハードウエアを用意して構築するのが一般的でした。つまり、Webサーバー、メールサーバー、ファイルサーバーなど、サーバーの種類や数が増えるごとに保有するハードウエアの台数も増えていたわけです。しかし、サーバーを仮想化することで、1台の物理サーバーの上に複数の仮想サーバーをソフトウエア的に作成し、同時に動かすことができるようになりました。

サーバーの仮想化を行うには、専用の仮想化ソフトウエアが必要になります。仮想化ソフトウエアとしては、主にPCで利用されているオラクルの「Virtualbox」、FJcloud-V(旧ニフクラ)で採用しているVMwareの「VMware vSphere®」、Microsoftの「Hyper-V」などが有名です。また、サーバーだけでなく、ストレージやネットワーク、デスクトップ環境やアプリケーションといったリソースの仮想化も利用されています。

※※https://clouddirect.jp.fujitsu.com/service/navi-beginner-virtualization より引用

仮想化ソフトウェア


https://it-ichiba.jp/info/0630/ より画像引用

1台のコンピュータ(物理マシン)の上で、複数の仮想的なコンピュータ(仮想マシン)を動作させるためのソフトウェア。
仮想マシンは独立した環境を持ち、それぞれが独自のオペレーティングシステムやアプリケーションを実行できる。
1台の物理マシンで複数の環境を構築し、学習、開発、テスト、サーバー統合などに活用できる強力なツール

基本的な仕組み


https://www.designet.co.jp/ossinfo/selection/virtual-infrastructure.html より画像引用

コンピュータのリソース(CPU、メモリ、ストレージ、ネットワーク)を抽象化して、複数の仮想マシンに分配する。これにより、仮想マシンは実際のハードウェアにアクセスしているように振る舞うようになる。

ホストマシン:仮想化ソフトウェアがインストールされている実際の物理コンピュータ。
ゲストマシン:仮想化ソフトウェアによって作成された仮想マシン。各ゲストマシンは独自のOSを持つ。

ホストOS:仮想化ソフトウェアを動作させているOS
ゲストOS:仮想化ソフトウェアによって実行する仮想的なOS

種類

ホスト型仮想化

仮想化ソフトウェアが既存のOS上で動作し、その上に仮想マシンを作成します。
(例)VirtualBox, VMware Workstation, Parallels Desktop。
・セットアップが簡単
・パーソナル用途や開発環境に適している

https://it-juku.jp/whatsvm/whatsvm02/ より画像・テキスト引用

ハイパーバイザー型

ハイパーバイザー(Hypervisor) は、仮想化を直接ハードウェア上で行うソフトウェア。
(例)VMware ESXi, Microsoft Hyper-V, Xen。
・高性能
・直接ハードウェアを制御するため、効率的
・サーバー仮想化に最適

https://it-juku.jp/whatsvm/whatsvm02/ より画像・テキスト引用

コンテナ型仮想化


https://it-juku.jp/whatsvm/whatsvm02/ より画像・テキスト引用

まとめ


https://it-ichiba.jp/info/0630/ より画像引用

mabomabo

GUI・CLI

GUI(グラフィカルインターフェース)

現在の一般的なOSにおいて採用されているインターフェース。
マウスやタッチパッドなどのポインティングデバイスを使って、画面上のメニューやアイコンをクリックしてさまざまな操作を行う。

CLI(コマンドラインインターフェース)

キーボードからコマンドを入力し、文字列として結果を出力するインターフェース。
Linuxサーバーを扱う際には基本的にCLIが使われている。

CLIのメリット

①作業効率がよくなる
②GUIの操作を覚えてもあまり意味がない
③プログラムが連携しやすい
④処理の自動化がしやすい

mabomabo

シェル

ユーザーがLinuxカーネルとやり取りするためのインターフェース
Linuxカーネルとユーザの橋渡しをする役割をもつ。
コマンドラインインターフェース(CLI)で動作し、ユーザーの入力を解釈してLinuxカーネルに命令を伝える。
シェルは基本的に標準入力(stdin)、標準出力(stdout)、標準エラー出力(stderr)を通じてユーザーとやりとりする。ユーザーがシェルで見ているもの(画面に表示されるもの)は、基本的にstdout, stderrの出力。


https://recruit.cct-inc.co.jp/tecblog/os/shell/ より画像引用


https://www.rstone-jp.com/column/110007/ より画像引用

動作の流れ
①入力の解釈
・ユーザーがターミナル(またはターミナルエミュレータ)にコマンドを入力。
・シェルがコマンドを解釈し、必要に応じて適切なシステムコールをLinuxカーネルに送信。
②カーネルの動作
シェルから受け取ったシステムコールを基に、カーネルがハードウェアやリソースを制御。
例:
ls コマンド:カーネルがファイルシステム情報を取得し、シェルに結果を返す。
echo "Hello, World!":カーネルが標準出力デバイス(画面)に文字列を表示。
③出力の返却
・カーネルが処理結果をシェルに返します。
・シェルは、その結果をユーザーに表示します。

システムコール

ユーザー空間(ユーザーが実行するアプリケーションなど)からカーネル空間(Linuxカーネルが動作する領域)に対してサービスを要求するためのインターフェース

ユーザー空間では直接ハードウェアやシステムリソースにアクセスできないため、システムコールを介してカーネルにリソース操作を要求

シェルの種類

sh (Bourne Shell)
開発者: Stephen Bourne
リリース年: 1977年
・Unixの最初のシェルの一つで、基本的なシェルスクリプトの構文を提供する。
・シンプルで軽量だが、機能は限られている。
・他のシェルのベースとなっており、互換性の高いスクリプトを書くために使われることがある。
使用例: シェルスクリプトの互換性を重視する場合や、古いシステムでの使用。

csh (C Shell)
開発者: Bill Joy
リリース年: 1978年
・C言語に似た構文を採用しており、プログラマーにとって親しみやすい。
・コマンド履歴やジョブコントロールなどの機能を初めて導入。
・スクリプトの実行速度が遅く、構文に一部問題があるため、現在ではあまり使われていない。
使用例: C言語に慣れているユーザーや、古いシステムでの使用。

bash (Bourne Again Shell)
開発者: Brian Fox
リリース年: 1989年
・shの拡張版で、Linuxのデフォルトシェルとして広く使われている。
・コマンド履歴、タブ補完、シェルスクリプトの高度な機能をサポート。
・他のシェルとの互換性が高く、スクリプトの移植性が良い。
使用例: ほとんどのLinuxディストリビューションやmacOS(Catalina以前)のデフォルトシェル。

tcsh (Tenex C Shell)
開発者: Ken Greer
リリース年: 1981年
・cshの拡張版で、コマンドライン編集や補完機能を強化。
・インタラクティブな使用に適しており、スクリプトの実行速度も改善されている。
・ただし、スクリプトの互換性や機能面ではbashに劣る部分がある。
使用例: cshの機能を強化したいユーザーや、特定の学術環境での使用。

zsh (Z Shell)
開発者: Paul Falstad
リリース年: 1990年
・bashの機能をさらに拡張し、高度なカスタマイズが可能。
・テーマやプラグインをサポートするフレームワーク「Oh My Zsh」が人気。
・強力な補完機能やスペルチェック、ディレクトリナビゲーションが特徴。
・macOS Catalina以降のデフォルトシェルとして採用されている。
使用例: 高度なカスタマイズを求めるユーザーや、macOSユーザー。

fish (Friendly Interactive SHell)
開発者: Axel Liljencrantz
リリース年: 2005年
・ユーザーフレンドリーな設計で、初心者にも使いやすい。
・シンタックスハイライト、自動補完、サジェスト機能などが標準で搭載。
・スクリプト構文は他のシェルと異なるため、互換性は低い。
・設定が簡単で、カラフルな表示が特徴。
使用例: 初心者や、インタラクティブな操作性を重視するユーザー。

※ログインシェルとは別のシェル(シェルの切り替え)を使うことはできるが、一時的なものであり、切り替え前のシェルに続いているため、exitコマンドで抜ける必要がある。

シェルとコマンド


https://utsu-programmer.com/credentials/linuc-shell/ より画像引用
① bashシェルがプロンプトを表示
② bashシェルがコマンドを解析
③ プロセスの表示
④ 処理を実行
⑤ プロセスの終了をbashに通知
⑥ ユーザーに結果を表示

mabomabo

Linuxカーネル

オペレーティングシステムの中核部分であり、ハードウェアとソフトウェアを仲介する役割を果たす。

https://qiita.com/uguis410/items/17ec1e447e9716bfdca7 より画像引用

主な機能

①プロセス管理
・実行中のプログラム(プロセス)を効率的に管理します。
・CPU時間を適切に割り当て、マルチタスクを実現。

②メモリ管理
・プログラムが効率的にメモリを使用できるよう制御。
・仮想メモリを提供し、物理メモリを最適化。

③デバイス管理
・デバイスドライバを介して、ハードウェア(キーボード、ディスク、ネットワークカードなど)と通信。
・抽象化されたインターフェースを提供し、ソフトウェアがハードウェアを簡単に利用できるようにします。

④ファイルシステム管理
・データの保存と取得を効率化。
・ext4やxfsなどの多様なファイルシステムをサポート。

⑤ネットワーク管理
・TCP/IPなどのプロトコルを用いてネットワーク通信を制御。

mabomabo

プロンプト

「今コマンド入力を待ち構えているので、何かコマンドを入力してください」ということを、シェルが意思表示している記号のこと

https://linuxfan.info/ubuntu-open-terminal-emulator より画像引用

// 一般ユーザの場合のプロンプト
$ <コマンド>
// スーパーユーザの場合のプロンプト
# <コマンド>

シェルを利用する際に \ (バックスラッシュ)を利用することができ、文末に入力してEnterキーを押すと、プロンプトが > に変わる。

$ echo \
>

セカンダリプロンプト:「まだコマンドラインが終了していないため、入力してください」という意味
この文字はシェル変数PS2でカスタマイズすることができる。
セカンダリプロンプトからも、\でさらに改行を続けていくことができる。最後にコマンドを実行したいところで、\をつけずにEnterキーを押せば全体のコマンドラインが実行される。

mabomabo

シェルスクリプト

コマンドなどを並べたテキストファイル
実行したいコマンド群を事前にファイルに記述しておき、そのファイルをシェルに指定しておくことで一連のコマンドをまとめて実行する
=一連の操作の流れを記述したファイルのこと

①「source」コマンドを使う
sourceコマンドは、指定されたスクリプトファイルの内容を現在のシェル環境で実行するためのコマンド
このコマンドは、シェル環境の変更(環境変数の設定など)を即座に現在のシェルに反映させたい場合に特に役立つ。

② bashシェルの起動時に引数として指定する

③ スクリプトファイルに実行権を付与する

https://www.kenschool.jp/blog/?p=4499 より画像引用

mabomabo

コマンド1

カーソル移動

コマンド 内容
Ctrl + b 後方に一文字分移動
Ctrl + f 前方に一文字分移動
Ctrl + a 行頭に移動
Ctrl + e 行末に移動
Alt + b 後方に単語1つ分移動
Alt + f 前方に単語1つ分移動
Cont + h
Cont + d
Cont + w
Cont + k カーソル位置から行末までを削除
Cont + u カーソル位置から行頭までを削除
Cont + y 最後に削除した内容を挿入
Cont + s 画面表示をロック
Cont + q 画面表示のロックを解除
Cont + l 画面を消去
Cont + p 1つ前のコマンド履歴へ移動
Cont + n 次のコマンド履歴へ移動
Cont + r 履歴を遡ってインクリメント検索
Tab 補完機能
補完候補の一覧表示

※文字は左から右へ移動→前方:左から右・後方:右から左
※ヤンク:bashではペーストのことを「ヤンク」という

mabomabo

Linuxはファイルからできている

Linuxではすべてがファイルとして表現されている。

ディレクトリ

ファイルを整理する入れ物(Windows, MacOSで「フォルダ」と呼ばれている)
Linuxはシステム全体で1つのディレクトリツリーしか持たない
・サブディレクトリ:ディレクトリの中にあるディレクトリ
・親ディレクトリ:あるディレクトリから見て1つ上にあるディレクトリ


https://www.partitionwizard.jp/partitionmagic/linux-file-system.html より画像引用

「 / 」:ルートディレクトリ

Linuxのディレクトリ構造はルートディレクトリを頂点とした階層構造

「パス」:ファイルへの道筋

パスの区切り文字は「 / 」で表す

各ディレクトリの役割


https://www.linuxfoundation.org/blog/blog/classic-sysadmin-the-linux-filesystem-explained より画像引用

/bin

実行ファイルをおくためのディレクトリ
Linuxシステムの動作に最低限必要な、重要度の高いコマンドを格納している
一般ユーザ・管理者の両方が使用するコマンド

/dev

デバイスファイルを格納するディレクトリ
※デバイスファイル:ディスクやキーボードなどのハードウェアをファイルとして扱えるように用意された特別なファイル

/etc

Linuxを管理・運用するうえで非常に重要なディレクトリ
Linux自体の設定に関わるファイルを格納しているディレクトリ。
設定ファイルを置くためのディレクトリ。設定ファイルがこの配下に置かれる。
※設定ファイル:Linuxで動作するさまざまなアプリケーションの設定のために使用されるテキスト形式の設定ファイル(コンフィグファイル)

/home

ユーザごとに割り当てられる、ホームディレクトリが配置されるディレクトリ
※ホームディレクトリ:Linuxのユーザごとに割り当てられる個人用ディレクトリのこと。ユーザ名がそのままディレクトリ名となっている。

/sbin

実行ファイルをおくためのディレクトリ
管理者ユーザ向けのコマンドが置かれている。

/tmp

一時的なファイルを置くためのディレクトリ。
アプリケーションの実行中に、作業途中の結果などを一時的にファイルとして保存する場合に、このディレクトリの下に作成するのが一般的。
※ファイルの永続的な保存先として利用してはいけない。

/usr

各種アプリケーションと、それに付随するファイルを置くためのディレクトリ
追加でアプリケーションをインストールした際に、実行ファイルやドキュメント、ライブラリなどがこのディレクトリの下に配置される。

/var

変化するデータを置くためのディレクトリ
アプリケーションを動作する上で作成したデータやログ、電子メールなどがこのディレクトリに格納される。
※たくさんのファイルが書き込まれ、容量を圧迫することが多いため、システム管理の上で注意が必要なディレクトリ。

カレントディレクトリ

現在自分が位置しているディレクトリのこと
※ワーキングディレクトリとも呼ばれる。

mabomabo

コマンド2

コマンド 内容
pwd カレントディレクトリを表示
cd カレントディレクトリの変更
ls ディレクトリ内のファイルを表示
cd ~ ホームディレクトリへ戻る
チルダ展開

コマンドの実行順序

①コマンド:実行するプログラムや処理
②オプション:コマンドの動作を変更・拡張するもの
③コマンドライン引数:コマンドやオプションの対象

※コマンドライン引数に - (ハイフン)で始まる追加の引数を指定できる

Fオプションで表示されるファイル種別

種類 記号
通常ファイル なし
ディレクトリ /
実行可能ファイル *
シンボリックリンク @

オプション指定の基本

・「 - 」:引数をとるオプション
・「 -- 」:ロングオプション
※引数をとるオプションではオプションと引数の間のスペースは省略可能
※引数をとるロングオプションでは、引数との間にスペースを入れるか、= 記号で引数を指定する

パス名展開

記号 意味
* 任意の文字列
? 任意の1文字
mabomabo

パス

絶対パス

ルートディレクトリを起点としてファイルやディレクトリのパスを示すこと

相対パス

現在のカレントディレクトリを起点として表記されるパス

「.」:カレントディレクトリ
「..」:親ディレクトリ

mabomabo

ファイル操作の基本1

mkdir:ディレクトリの作成

$ mkdir [オプション] <作成するディレクトリ>
// 深いディレクトリを一気に作成(途中のディレクトリあり)
$ mkdir file1/2025/02
// オプション
//  -p:深いディレクトリを一気に作成(途中のディレクトリなし)
// 事前に2025, 02というディレクトリを作る必要がない
$ mkdir -p file1/2025/02

touch:ファイルの作成

$ touch <新しいファイル名> <新しいファイル名>

touchコマンドでのファイル作成は、誤って既存のファイル名を指定しても、内容が上書きされたり削除されたりしない

rm・rmdir:ファイル・ディレクトリの削除

// 単一ファイルの削除
$ rm [オプション] <削除するファイル名> <削除するファイル名>

// 複数ファイルの削除
$ rm file1 file2 file3
$ rm *.html

// 再帰的にディレクトリの削除 -r オプション
// ディレクトリの中のファイルなども削除される
$ rm -r dir1

// 削除の確認 -i オプション
$ rm -i file1

rmコマンドを実行するとファイル本当に削除されてしまうため、コマンドの実行前には常に注意が必要

$ rmdir <ディレクトリ名>

中にファイルがあるとエラーになる。
先頭が . (ドット)で始まる隠しファイルが表示されないため、ls -a dir1のようにして隠しファイルがないかどうかを確かめること

mabomabo

ファイル操作の基本2

cat:ファイルを表示

// ファイルの表示
$ cat [オプション] <ファイル名>

// ファイルと連結して表示
$ cat [オプション] <ファイル名> <ファイル名>

// オプション
// -n:行番号をつけて表示

ファイルの内容が空の場合、何も表示されない。
※引数にファイルを指定しないとコマンド実行後、カーソルが止まり、プロンプトが表示されなくなる。
Ctrl + d でキーボードからの入力終了を指示する。

less:スクロール表示

長いファイルの内容が見たいときに使う。
引数に指定したファイルの内容を1画面ごとに表示して、上下にスクロールすることができる。

$ less [オプション] <ファイル名>

less コマンドのスクロール操作

コマンド 内容
f, Ctrl + v 1画面下にスクロール
b 1画面上にスクロール
j, Ctrl + n 1行下にスクロール
k, Ctrl + p 1行上にスクロール
q lessコマンドの終了
/ ファイル内の検索
検索したい文字を入力してEnterキーを押す

less コマンドの検索操作

コマンド 内容
/<文字列> 下方向に向かって検索
?<文字列> 上方向に向かって検索
n 次の検索結果に移動
N 前の検索結果に移動
mabomabo

ファイル操作の基本3

cpコマンド:ファイル/ディレクトリのコピー

$ cp [オプション] <コピー元> ... <コピー先>

// i オプション
// 上書きの確認
// コピー先ファイルが存在する場合に本当に上書きしてよいか確認されるようになる
$ cp -i <コピー元> ... <コピー先>

// r オプション
// ディレクトリのコピー
$ cp -r <コピー元> ... <コピー先>

mvコマンド:ファイルの移動

$ mv [オプション] <移動元> ... <移動先>

// ファイル名の変更も可能。その場合、元のファイルは存在しなくなる

// -i オプション:上書きの確認
$ mv -i file1 file2
    mv: `file2` を上書きしますか?
// y -> yes , n -> no

lnコマンド:リンクを貼る

$ ln [オプション] <リンク元ファイル名> <リンク名>

// -s オプション:シンボリックリンク作成
$ ln -s <リンク元ファイル名> <リンク先>

// シンボリックリンクの確認ができる
$ ln -l

リンク:ファイルに別名をつける機能のこと

リンクを貼る:ファイルに別名をつけること


https://tech.pjin.jp/2022/08/31/ln より画像引用

ハードリンク

1つのファイルの実体に複数の名前を付ける機能。
ハードリンクを持つファイル実体は、すべてのハードリンクがなくなったときに削除される。
・ディレクトリに対して作成できない。
・異なるディスク間をまたがることができない。

シンボリックリンク

リンク先のパス名が書かれた小さな特殊ファイル。リンク先がファイルの実体。
ファイルシステム上のファイルやディレクトリを指す特殊な種類のファイル。
別のファイルやディレクトリへのパスを含んでいる。リンクを開くと、実際には参照先のファイルやディレクトリがアクセスされる。


https://www.infra-linux.com/menu-linux3/hard-symlink-link/ より画像引用

リンクの利用方法

①長いパス名を省略
②複数バージョンのプログラムを共存させる

mabomabo

ファイル検索


https://www.linkedin.com/pulse/file-searching-pattern-matching-linux-find-locate-grep-muntakim-n4s3c より画像引用

findコマンド:ディレクトリツリーからファイルを探す

指定したディレクトリ直下のファイルだけでなく、ディレクトリツリーを順に下りながら検索条件に一致するすべてのファイルを表示する。

https://active.nikkeibp.co.jp/atcl/act/19/00492/100300009/ より画像引用

$ find <検索開始ディレクトリ> <検索条件> <アクション>

// -name, -iname:ファイル名で探す
// 例
$ find . -name file.html -print

// -type:ファイルの種類で探す
// 例
$ find . -type d -print

// -a:複数の検索条件を指定
// 例
$ find . -type f -a -name '*.txt' -print

検索条件に何も指定しなかった場合は、すべてのファイルとディレクトリが対象になる。
※アクションがない場合、-print が指定されたとみなされる

ファイル名で探す(-name, -iname)

※ -name で * や ? を使用する場合は、''(シングルクォート)を必ずつけること
 →* などの記号がパス名展開と解釈されてしまうから。
◎メタ文字をコマンドに渡したいときは、どこまでをシェルが展開してどのような文字列でコマンドが実行されるか、ということを意識する必要がある。

パス名展開(Pathname Expansion)

シェルがワイルドカード(*, ?, [])を含むパス名を、自動的に実際のファイルやディレクトリ名に置き換える処理のこと。
""(ダブルクォート) や ''(シングルクォート)で囲むとパス名展開が無効になる。

ファイルの種類で探す(-type)

指定 ファイル種別
-type f 通常ファイル
-type d ディレクトリ
-type l シンボリックリンク

複数の検索条件を指定(-a)

findコマンドでファイルを探すとき、検索条件を-a(AND)で区切って並べることで、複数の検索条件を同時に指定するAND検索ができる。

locateコマンド:ファイル名データベースからファイルを探す

パス名の一部を指定してファイルを探すためのコマンド。
ファイル名を専用のデータベースから検索するため、ディスクをスキャンしてファイルを探すfind コマンドに比べて高速に検索ができる。
指定したパターンがファイルパスのどこかに含まれていれば一致したものとみなされて表示される。

ファイルの検索

$ locate [オプション] <検索パターン>

// -i または --ignore-caseオプション:大文字小文字を無視させたい
// 例
$ locate -i notes

// -b または --basenameオプション:ファイル名だけを検索対象にする
// 例
$ locate -b python

// 複数の検索パターンを指定するとOR検索になる
$ locate docs document

// -A または -all オプション:複数の検索パターンに一致する検索(AND検索)
$ locate -A bash doc

※locateコマンドはインストール時に、ファイルパスのデータベースを1日1回作成する。
そのため、以下のケースがありえる。
・locate コマンドで表示したファイルが実際にはディスク上に存在しない
・locate コマンドでは表示されないのに、ディスクがファイルに存在する
◎locate コマンドは作成してからしばらく経ったファイルを見つけるのに向いている。

mabomabo

コマンドの使い方を調べる

--help オプション

コマンド自身のヘルプメッセージを表示する。
表示内容
・使用方法
・コマンドの概要
・利用可能なオプション一覧とその意味
・その他の参考資料の紹介

man コマンド:マニュアルを表示する

オンラインマニュアル(電子化されたマニュアル)を表示するコマンド。
--help オプションよりも詳しい解説がされている。
コマンドのマニュアル、Linuxの設定ファイル、ライブラリなどのマニュアルも含まれる。

man <調べたいコマンド名>

// キーワードで調べる
$ man -k <キーワード>
// 例
$ man -k copy

// セクションで調べる
$ man <セクション番号> <名前>

※ less コマンドと同じ

セクション

括弧内の数字はセクション番号

man のセクション番号とその内容

セクション番号 内容
1 コマンド
2 システムコール
3 ライブラリ関数
4 デバイスファイル
5 ファイルの書式
6 ゲーム
7 その他
8 システム管理コマンド
9 カーネルルーティン

help コマンド:bash組み込みコマンドの使い方を表示

シェルの中に組み込まれている cd のようなコマンド、組み込みコマンドは man コマンドでマニュアルを表示できない。
そのため、help コマンドで調べる。

$ help <調べたいコマンド>

help はbash の組み込みコマンドのヘルプメッセージを表示する。
※引数を指定しないと、help コマンドで閲覧できる項目の一覧を表示される。

mabomabo

コマンドを探す

コマンドの実行ファイルは$PATHから探す
サーチパス(パス):$PATHで設定する、コマンドを探すディレクトリのこと。
パスがあるおかげで、コマンドが実際にどこにあるのかを意識せずにコマンド名だけ入力すれば実行できるようになる。

which コマンド:コマンドのフルパスを表示

指定されたコマンド名をサーチパスから探して、見つかった実行ファイルのフルパスを表示する。
※パスの中から見つかった最初のコマンドだけ表示する。

which [オプション] <コマンド名>

// -a:異なるディレクトリに同じ名前のコマンドが複数配置されているとき、すべての実行ファイルの場所を確認できる。
// 例
which -a ping

$PATH:環境変数の一種

コマンドや実行ファイルが保存されているディレクトリのリストを保持する。
OSがコマンドやプログラムを探す場所を指定するための重要な設定。
シェル(Bashなど)がコマンドを探す際に参照するディレクトリのリスト。このリストは、環境変数 PATH に保存されている。

※環境変数:OSやアプリケーションが動作する際に使用する設定値や情報を保持するための仕組み。環境変数は、システム全体や特定のユーザーに対して設定され、プログラムが実行される際に参照される。

$ echo $PATH
// 表示される文字列は、コマンドを探すディレクトリを: で連結したもの

※コマンド実行の流れ

https://www.reqtc.com/blog/shell-kernel-bash.html より画像引用

ファイル名を指定して実行する場合のシェルの動き

ターミナルで単にファイル名を指定して実行しようとした場合(例:my_script.sh や my_program)、シェルは以下の手順を踏む。

① 特別なパスの確認

まず、ファイル名がスラッシュ (/) を含んでいるかどうかを確認する。

スラッシュを含む場合 (例: ./my_script.sh, /home/user/my_program)
シェルは、指定されたパスを直接参照し、そのファイルを実行しようとする。
この場合、サーチパス (PATH) は検索されない。これは、あなたが特定の場所にあるファイルを明示的に実行したいという意図を示すため。

スラッシュを含まない場合 (例: my_script.sh, my_program)
シェルは、ファイル名にスラッシュが含まれていない場合、それをコマンド名と解釈する

② コマンド名と解釈した場合のサーチパス検索

ファイル名にスラッシュが含まれていない場合、シェルはそれをコマンド名とみなし、PATH 環境変数に登録されているディレクトリを順番に検索し、その名前の実行可能ファイルを探す。

③ 実行またはエラー

指定されたパス(スラッシュを含む場合)にファイルが存在し、実行権限があれば、シェルはそのファイルを実行する。
存在しない場合や実行権限がない場合は、エラーメッセージが表示される。

サーチパスの検索(スラッシュを含まない場合)で実行可能ファイルが見つかれば、シェルはそのファイルを実行する。見つからなければ、「command not found」のようなエラーメッセージが表示される。

mabomabo

テキストエディタ

テキストファイル

テキスト(文字列)が書かれたファイル
cat コマンドや less コマンドで表示できる。
Linuxでは、設定ファイルやアプリケーションのデータファイルなどの多くには、テキストファイルが使われている。
Linuxを使う上では、テキストファイルの編集は避けては通れない。

バイナリファイル

画像ファイルや音声ファイル、Linuxコマンドの実行ファイル(例:catコマンドの実体ファイルである/bin/cat)など。

【実行可能ファイル(バイナリファイル)とテキストファイルの違い】

実行可能バイナリファイル
・OSはファイルの先頭にある「マジックナンバー」などで「これは実行ファイルだ」と認識し、そのままCPUが解釈できる機械語としてロードし実行する。
・ファイルには「実行権限(execute permission)」が設定されている必要がある。

テキストファイル
OSは単に「データファイル」として扱い、機械語ではないので直接実行はしない。
ただし、その中に書かれたコードを読み取って解釈し実行する「インタプリタ」があれば実行できる(例:シェルスクリプト、Pythonスクリプトなど)

シェルスクリプトなどの例
#!/bin/bash のような「シバン(shebang)」行がファイルの先頭にあると、Linuxはそのファイルを直接実行するときに指定されたインタプリタ(ここではbash)で中身を読み解いて実行する。
逆にシバンがなければ、明示的にbash script.shのようにインタプリタ経由で実行する。

mabomabo

Vim

デフォルトのエディタ。

Vimの基本的なコマンド

コマンド 内容
:q Vimを終了する
:w ファイルを上書き保存する
:w <ファイル名> 名前を付けて保存する
:q! ファイルを保存せずVimを終了する
h 左に移動
j 下に移動
k 上に移動
l 右に移動
x カーソル位置の文字を削除
i カーソル位置の左に文字を追加
a カーソル位置の右に文字を追加

※コマンドが実行できず、直接文字列が入力されるようになった場合、Escキーを何度か押す
※ノーマルモード:元の状態
※インサートモード:テキストが入力できる状態

ファイルを開く

$ vim <ファイル名>

便利なカーソル移動

単語単位でのカーソル移動

コマンド 内容
w 前方に単語1つ分移動
b 後方に単語1つ分移動
W スペース区切りで前方に単語1つ分移動
B スペース区切りで後方に単語1つ分移動
0 行頭に移動
$ 行末に移動
gg 1行目に移動
G 最後の行に移動
<数字>G <数字>行目に移動

カット・コピー・ペースト

Vimでの呼び方

一般的なエディタでの名称 Vim
カット デリート(delete)
コピー ヤンク(yank)
ペースト プット(put)

デリート(delete)

dの後にカーソル移動コマンド(どこまでデリートするかの範囲)を指定する

コマンド 内容
d$ 行末までをデリート
d0 行頭までをデリート
x
dl
1文字をデリート
dw 単語1つをデリート
dgg 最初の行までをデリート
dG 最後の行までをデリート
dd 現在カーソルのある行をデリート

プット(put)

コマンド 内容
p 貼り付け

ヤンク(yank)

yの後にカーソル移動コマンド(どこまでデリートするかの範囲)を指定する

コマンド 内容
y$ 行末までをヤンク
y0 行頭までをヤンク
y
yl
1文字をヤンク
yw 単語1つをヤンク
ygg 最初の行までをヤンク
yG 最後の行までをヤンク
yy 現在カーソルのある行をヤンク

その他の操作

コマンド 内容
J 下の行と連結
u 直前の編集操作を取り消して前の状態に戻る
Ctrl + r u(undo)の取り消し

※アンドゥ(undo)・リドゥ(redo)

検索

コマンド 内容
/<文字列> 上方向に向かって<文字列>を検索
?<文字列> 上方向に向かって<文字列>を検索
n 次の検索結果に移動
N 前の検索結果に移動

/による検索は現在のカーソル位置から始まる。
ファイルの初めから検索したい場合、いったんggを押し、ファイルの先頭に戻ってから検索するといい。

置換

:%s / <置換元文字列> / <置換後文字列> / g

g がない場合、行内で最初に一致した箇所のみが置換される。

置換フラグの種類

フラグ 説明
g 行全体でパターンに一致するすべての箇所を置換
i 大文字・小文字を区別せずに置換
c 置換する前に確認プロンプトを表示
n 置換せずに、一致した箇所の数を表示

ヘルプとドキュメント

$ vimtutor
:help

// コマンドや単語に関するヘルプを表示
:help <コマンド or 単語>

Vimの画面が上下2つに分割され、上側の画面にヘルプが表示される。

リンクが貼られている場合のコマンド

コマンド 内容
Ctrl + ] リンク先に移動
※リンクにカーソルを合わせてから行なう
Ctrl + t リンク先から元の場所に戻る
mabomabo

bash の設定1

エイリアス

わかりやすい別名を与えて、コマンドを使いやすくするための機能

// エイリアスを設定
alias <名前>='<コマンド>'

// エイリアスの確認
type <名前>

// エイリアスの削除
unalias <名前>

エイリアスを一時的に無効にする方法

①コマンドのフルパスを指定
②実行したいコマンドの前に command を追加する
③コマンドの前に\ または ¥を追加する
※unalias コマンドを使うとそれ以降のすべての操作に影響するため、上記のようなケースで対応できる。

bash のオプション

オプションは1つ1つの機能ごとの「オン」「オフ」いずれかの値を取り、これによりbash の各機能の有効・無効を指定できる。

オプションの設定に使用するコマンド

①set コマンド

シェルの基本的な動作を制御するためのコマンド

書式
set -o / +o <オプション名>

-o:オン
+o:オフ
詳しくは man bash 参照

よく使用されるset コマンドのオプション

オプション名 内容
ignoreeof Ctrl + D を押してもシェルを終了しない
noclobber すでに存在するファイルをリダイレクトで上書きしない
noglob パス名展開を無効にする

ignoreeof (ignore end of file)
(EOF: End Of File) キーによる意図しないターミナルセッションの終了を防ぐためのもの。
・通常、ターミナルで Ctrl + D キーを押すと、シェルは入力の終わり (EOF) を検出し、セッションを終了する。
・set -o ignoreeof コマンドを実行してこのオプションを有効にすると、シェルはこの EOF を無視し、セッションを終了しない。
・これにより、Ctrl + D キーを誤って押してしまった場合に、セッションが予期せず終了するのを防ぐことができる。

noclobber (no clobber)
ファイルのリダイレクト時における上書きを防止するためのもの。
・通常、リダイレクト(>)を使ってファイルに書き込む際、指定したファイルが既に存在する場合は、そのファイルは上書きされる。
・set -o noclobber コマンドを実行してこのオプションを有効にすると、既存のファイルへのリダイレクトが禁止され、上書きを防ぐ。
・既存のファイルを上書きしたい場合は、リダイレクトの代わりに >| を使用します。

noglob (no globbing)
ファイル名のパターンマッチング(グロブ)を無効にする。
・通常、*? などのメタ文字を含むファイル名を指定すると、シェルはファイルシステム内の該当するファイルに展開(グロブ展開)する。
・set -o noglob コマンドを実行してこのオプションを有効にすると、メタ文字を含むファイル名はそのまま文字列として扱われ、グロブ展開は行われない。
・ファイル名にメタ文字そのものを含むファイルを取り扱う場合などに有効。

②shopt コマンド

Bash固有の細かい動作を制御するためのコマンド

書式
shopt -s / -u <オプション名>

-s:オン
-u:オフ

※shopt で指定するオプション名は set で指定するものとは異なる

※詳しくは bash マニュアルの man shopt コマンド参照

set と shopt の違いまとめ

項目 set shopt
対象 シェル全体の基本的な動作 Bash固有の細かい動作
用途 シェルスクリプトの制御やデバッグ シェルの便利機能や動作の微調整
オプションの種類 シェルの基本的なオプション
(例: -e, -u)
Bash固有の拡張オプション
(例: dotglob, extglob)
シェルの種類 ほとんどのシェルで利用可能 Bash固有のコマンド
mabomabo

リダイレクト (>)

コマンドの出力をファイルに保存するために使用する。
既存のファイルがある場合、その内容は上書きされる。
※既存の内容が失われる

書き方
コマンド > ファイル名
echo "Hello, World!" > output.txt

① output.txtというファイルが存在しない場合
output.txtというファイルが作成され、その中にHello, World!というテキストが保存される。

② output.txtが既に存在していた場合
その内容はHello, World!で上書きされる。
※既存のファイルの内容は完全に上書きされる。つまり、output.txt に以前保存されていた内容はすべて削除され、新しい内容に置き換えられる。

cat コマンドと組み合わせると自由な内容でファイルを作成することができる。

cat > output

◎Linux ではデータの読み込みが最後になると、このEOF(End of File) が入力され終わる決まりがある。

アペンド (>>)

コマンドの出力を既存のファイルの末尾に追加するために使う。
既存のファイルがある場合、その内容は保持され、新しい内容が追加される。
※既存の内容は保持される

書き方
コマンド >> ファイル名
echo "This is a new line." >> output.txt

① output.txtが既に存在していた場合
output.txtの末尾にThis is a new line.というテキストが追加される。

② output.txtというファイルが存在しない場合
新しいファイルが作成される。

標準出力と標準エラー出力を1 つのファイルに出力したい場合

ls -l example > ls-l-output-second 2>&1

一覧表

コマンド 意味
> 出力をファイルに保存(上書き)
>> 出力をファイルの末尾に追加
2> エラーメッセージをファイルに保存
> output.log 2>&1 標準出力と標準エラー出力を同じファイルに保存
mabomabo

パイプ( | )

コマンドとコマンドを「|(パイプ)」でつなげることでパイプの前のコマンドを後ろのコマンドの標準入力とすることができる。

$ ls -l /usr/bin | less

端末をリモート操作している場合やデスクトップ環境がインストールされていないLinux 環境の場合は、パイプでつなげる方法を知っておくと大変便利

mabomabo

grep コマンド

ファイルの中からデータを検索。
また、| grep とすることで、標準入力から入ったデータに対し検索を行なうことも可能。

基本
grep [オプション] 検索条件 <指定ファイル>

// -e オプション
文字列を検索パターンとして扱う。

// -i オプション
検索パターンと入力ファイルの双方で、英大文字と小文字の区別を行わない。

// -v オプション
検索パターンとマッチしなかった行を選択する。
 
mabomabo

正規表現

記号 意味
^ 行頭を表す
$ 行末を表す
. 任意の一字を意味する
* 直前文字の0 回以上の繰り返しを意味する
[...] ... の中の任意の一字を意味する
[^...] ...の文字が含まれないことを意味する
Y 正規表現の記号をエスケープする
mabomabo

bash の設定2

シェル変数

・Bashやshなどのシェルスクリプト内で使用される変数
・bash で使用される変数
・親プロセス内のデータ 
・シェルスクリプト内での一時的なデータ保持に適している。
・シェル変数は現在のセッションでのみ有効
※子プロセスには引き継がれない
※シェルが外部コマンドを実行:新しいプロセス(子プロセス)を作って実行している


https://l-study.arcjp.com/lpic/linux-essentials/linux-essentials-online-text/le-12-1/ より画像引用


https://utsu-programmer.com/credentials/linuc-shell/ より画像引用

変数の設定

書式
<変数名> = <>
// シェル変数 var に値を設定
$ var='test'

// シェル変数 var を参照
$ echo $var

・設定した変数は$<変数名>という形で参照できる。
・変数を設定する際、=の左右にスペースをつけてはいけない。

https://www.infra-linux.com/menu-lpic3/shell-env-op-cmd/ より画像引用

PS1 - プロンプト設定

シェルのプロンプトを設定するには、シェル変数に文字列を設定する。
PS1変数は、設定した文字列がそのままプロンプトとして表示される。


https://linuxfan.info/ubuntu-open-terminal-emulator より画像引用

$ PS1='bash> '
// 出力
[user名]> 

プロンプトで利用できる記号

記号 内容
\d [曜日 月 日]という形式の日付
\h ホスト名のうち、最初の.までの部分
\H ホスト名
\n 改行
\t HH:MM:SS:形式の現在時刻
\u ユーザ名
w カレントディレクトリ
W カレントディレクトリの末尾のディレクトリ名
\$ root ユーザの場合:#
それ以外のユーザの場合:$
\\ \そのもの

PATH - コマンド検索パス

シェル変数PATHには、コマンドを実行する際にシェルがコマンドの実体ファイルを探すディレクトリを指定する。
この変数には、シェルがコマンドを探すディレクトリを「:」区切りで連結した文字列が設定されている。

自分独自のコマンドを配置する場所として、ホームディレクトリ下に作成した bin という名前のディレクトリがよく使われる。


https://qiita.com/_mi/items/1e1f1aa9e40ef6cfb935 より画像引用


https://www.reqtc.com/blog/shell-kernel-bash.html より画像引用
※④では、bashは、execveなどのシステムコールを発行し、カーネルに実行ファイルの実行を要求する。

LANG - ロケール

ロケール(Locale):言語や国、地域などを特定するための識別子
表示する言語や日付の書式などは、ロケールを基準にして切り替えられる。

その他のシェル変数

代表的なコマンドライン履歴関連のシェル変数

シェル変数名 内容
HISTFILE コマンド履歴を保存するファイル名
デフォルト値:~/.bash_history
HISTFILESIZE 履歴ファイルに保存するコマンドライン履歴の最大行数
HISTSIZE コマンドライン履歴を保持する最大行数

シェルの状態関連のシェル変数

シェル変数名 内容
HOME ホームディレクトリ
SHELL ログインシェルのパス
PWD カレントディレクトリ

PATH="$PATH:$HOME/bin" の意味

この記述は、そのファイルが実行された時点で、環境変数 PATH の値を変更するコマンド
ファイルの中に PATH="$PATH:$HOME/bin" と記述した場合、そのファイル自体がサーチパスに設定されるわけではない。

PATH="$PATH:$HOME/bin" という記述は、PATH 環境変数の値を変更するコマンドであり、ファイル自体をサーチパスに設定するわけではない。
このコマンドを実行すると、PATH にユーザーのホームディレクトリ下の bin ディレクトリが追加される。
この変更を現在のシェル環境に反映させるためには、source コマンドでファイルを実行する必要がある。
この設定を行うことで、$HOME/bin ディレクトリに配置した実行可能ファイルを、コマンド名だけで実行できるようになる。

この記述は2つの部分から構成されている。
[PATH="$PATH":]
「現在の PATH 環境変数の値をそのまま新しい PATH 変数に代入する」という意味。つまり、既存のサーチパスを維持する。

[:$HOME/bin"]
コロン : を区切り文字として、ユーザーのホームディレクトリ ($HOME) の下の bin ディレクトリというパスを、新しい PATH 変数の末尾に追加するという意味。

ファイルが実行された場合の効果
この記述が書かれたファイルが直接実行されるか、source コマンドによって現在のシェル環境に読み込まれて実行されるかによって、効果が異なる。

1. ファイルが直接実行された場合 (bash ファイル名)
新しいサブシェルが起動し、そのサブシェル内でファイルの内容が実行される。
サブシェル内で PATH="$PATH:$HOME/bin" が実行されると、そのサブシェル内の PATH 環境変数が変更される。
しかし、この変更は親シェル(あなたがコマンドを入力した元のシェル)の PATH 環境変数には影響を与えないため、 サブシェルが終了すると変更は失われる。

2. ファイルが source コマンドで実行された場合 (source ファイル名 または . ファイル名)
ファイルの内容が現在のシェル環境に直接読み込まれて実行される。
PATH="$PATH:$HOME/bin" が実行されると、現在のシェル環境の PATH 環境変数が変更される。
この変更は、現在のシェルセッションが続く限り有効。
また、このシェルから起動される後続のコマンドやスクリプトにも引き継がれる。

配置場所について
上記の記述は、PATH 環境変数に $HOME/bin ディレクトリを追加するものであり、ファイルを特定の場所に配置する指示ではない。

もし $HOME/bin ディレクトリを作成し、その中に実行したいスクリプトやプログラムを配置した場合、上記の PATH の設定を行なうことで、そのディレクトリにあるコマンドを、パスを明示的に指定しなくても実行できるようになる。

mabomabo

環境変数

シェル(ターミナル)やプログラムが動作するときに参照する値。
環境変数は、プログラムやコマンドが動作するときの設定情報として使われる。
ファイルシステム内のパスやアプリケーションの動作を制御する。
環境変数は、親プロセスから子プロセスにコピーされる。この仕組みにより、外部コマンドを使える。
シェルのプロセス内に格納される。
環境変数自体は export コマンドで設定される。

シェル変数と環境変数の関係

シェル変数
・シェル内で定義された変数で、現在のシェルセッション内でのみ有効。
・シェル変数は、子プロセス(外部コマンドなど)には引き継がれない。

環境変数
・シェル変数の一部で、exportコマンドを使って「環境変数」として設定されたもの。
・環境変数は、子プロセスにも引き継がれる。
・環境変数はシェル変数の「中」に存在する。環境変数は、シェル変数の一部としてシェルの内部に存在する。
環境変数はシェル変数の一部。すべての環境変数はシェル変数だが、すべてのシェル変数が環境変数であるわけではない。

外部コマンド(例えば ls, grep, python など)は、環境変数を参照して動作し、特に重要なのが PATH。
※外部コマンドはシェルの一部ではなく、独立した実行ファイル(プログラム)


https://utsu-programmer.com/credentials/linuc-shell/ より画像引用


https://milestone-of-se.nesuke.com/sv-basic/architecture/env-variable/ より画像引用

外部コマンド
実行ファイルとしてファイルシステム上に存在するコマンド

組み込みコマンド
シェル自体に内蔵されているコマンド

※ type コマンドにより外部コマンドの判別をする。
シェル変数の値を外部コマンドは参照することができない
環境変数は、シェル上だけでなく、外部コマンドでも常に設定を反映しておけるよう、外部コマンドからも値を参照できるようにした変数
※このような値を参照できる・できないはシェルと外部コマンドのスコープの違いによるもの

シェル変数と環境変数の違い

https://qiita.com/hitorigotsu/items/95cc3a89c7dc396ee3d5 より画像引用

主な環境変数

環境変数名 説明
PATH コマンドやプログラムを検索するためのパスリスト
PWD カレントディレクトリの絶対パス
HOME ユーザーのホームディレクトリ
USER 現在のユーザー
HOSTNAME ホスト名
PS1 プロンプトの表示文字列
PS2 複数行にわたる入力時のプロンプト
HISTFILE コマンド履歴を格納するファイルの定義
HISTSIZE コマンド履歴の最大値
HISTFILESIZE HISTFILEに保存する履歴数

PATH

「どのディレクトリにあるコマンドを実行できるか」を決める環境変数。
外部コマンドを探すための環境変数。
外部コマンドの場所を指定するための仕組み。
コマンドの検索対象となるディレクトリ一覧が設定されている。
:(コロン)で区切られたパスのリストが表示される。
ファイルシステム内の実行ファイルの場所を指定。
※PATH に指定したプログラムのパスがないと、シェルは実行できない。
※PATHはディレクトリの一覧を保持する環境変数であって、ファイルのパスを設定するものではない。
 →ファイルを直接PATHに追加するのは適切ではない。

シェルやプログラムは、コマンドを実行する際に、PATHに指定されたディレクトリを順番に検索し、最初に見つかった実行ファイルを実行する。
※このような仕組みにしている理由の一つは、コマンド(実行ファイル)やプログラムが独立したモジュールとして扱われることが挙げられる。PATHを通じてこれらのモジュールを呼び出すことで、システムの他の部分に影響を与えずに機能を追加・変更できるようになる。

/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin

(例)ls コマンドを実行 → Linuxはリストの中から ls を探し、実行する

PATH にないディレクトリのプログラムを実行する方法

通常、PATHにないコマンドを実行すると、「command not found」と表示されてしまう。

①フルパスで実行する:直接プログラムを実行する

/opt/practice/example

②PATH に追加する

export PATH=$PATH:/opt/practice

printenv コマンド:環境変数の表示

現在シェルに設定されている環境変数を表示する

export コマンド:環境変数の設定

書式
export <シェル変数名>

export すると 親プロセスの環境変数テーブルに登録される
子プロセスが作られるとき、環境変数がコピーされる
ディレクトリを追加することで、そこにあるプログラムやスクリプトを実行できるようになる。
※ファイルを直接PATHに追加するのは適切ではない。

mabomabo

シェルのコマンド実行の流れ


https://lpi.or.jp/lpic_all/linux/intro/intro09.shtml より画像引用

(前提)
シェルには組み込みコマンド(builtin)と 外部コマンドの2種類のコマンドがある。
シェルはコマンドを受け取ったときに、まず 「これはビルトインか?外部コマンドか?」 を判断して、実行方法を変えている。
外部コマンドは実行ファイルとしてシステムに存在する。

①シェルがコマンドを受け取る
ターミナルに例えば ls と入力して Enter を押すと、シェル(Bash などのコマンドラインプログラム) がそのコマンドを解釈しようとする。

②ビルトインコマンドか外部コマンドかをチェック
シェルは、入力されたコマンドを解釈し、実行すべきプログラムを特定する。
cd, echo, export, alias などの ビルトインコマンド は、シェル自身が内部で処理するので PATH を検索せずにすぐ実行。
シェル組み込みコマンドの場合、シェルは直接コマンドを実行し、カーネルにシステムコールを発行しません。

③ビルトインでなければ、PATH から外部コマンドを探す
ls, grep, python, vim などの外部コマンド は、PATH 環境変数に含まれるディレクトリから該当する実行ファイルを探して起動する。
外部コマンドだと分かったら、シェルは PATH に設定されているディレクトリを順番に探して実行ファイルを見つける。ファイルシステムが該当する実行ファイルを見つける。
(例)ls の場合、シェルは /bin/ls などの場所にある ls の実行ファイルを探し、見つかれば実行。
外部コマンドの場合、シェルは fork() システムコールをカーネルに発行し、子プロセスを生成する。
※ fork():子プロセスを生成する

④システムコールの発行
子プロセスは、exec() システムコールをカーネルに発行し、指定されたプログラムを実行するように置き換えられる。exec() の引数は実行するファイルパス。

⑤Linuxカーネルによる処理
カーネルは、シェルからのシステムコールを受け取り、要求された処理を実行する。
・fork() システムコールの場合、カーネルは新しいプロセスを生成し、メモリ空間やファイル記述子などをコピーする。
・exec() システムコールの場合、カーネルは指定されたプログラムをメモリにロードし、実行を開始する。処理結果は子プロセス上で展開される。
その他のシステムコール(例:ファイル入出力、メモリ管理)の場合、カーネルは対応する処理を実行する。

⑥カーネル(OS)がプログラムをロードし、コマンドを実行する
・シェルは execve() などのシステムコールを使って外部コマンドを起動
・OS(カーネル)がファイルを開き、プログラムをメモリ上にロードして実行する
・カーネルは、子プロセスまたはシェル組み込みコマンドの実行を制御する。
・プログラムは、カーネルにシステムコールを発行して、必要なハードウェア資源(例:ファイル、メモリ、ネットワーク)にアクセスする。

※子プロセスが exec() システムコールを発行するとき、カーネルに対して実行するプログラムファイルのパスを伝える。
※カーネルは、指定されたファイルの内容をメモリにロードし、子プロセスで実行する。
※この仕組みにより、シェルは外部コマンドを子プロセスで実行し、親プロセスであるシェル自身は次のコマンド入力を受け付けることができる。

⑦実行結果をシェルに返す
・プログラムの実行結果は子プロセス上で結果を出力し、カーネルがシェル(親プロセス)に結果を渡し、標準出力に出力され、ターミナルに表示される。
・ls が /home/user の内容を取得し、シェルに返す。
・シェルが結果をユーザーに表示。

⑧見つからなければ「コマンドが見つからない」エラーを出す
ビルトインでもなく PATH にもない 場合は、command not found エラーになる。

⑨プロセスの終了
プログラムの実行が完了すると、子プロセスは exit() システムコールをカーネルに発行して終了する。
カーネルは、子プロセスの終了処理を行い、親プロセスであるシェルに終了ステータスを通知する。
シェルは、子プロセスの終了を待ち、次のコマンド入力を受け付ける。

※プロセスとメモリ
プロセスが生成されると、OSはプロセスに対して固有の仮想メモリ空間を割り当てる。
この仮想メモリ空間は、他のプロセスからは隔離されており、プロセスは他のプロセスが使用しているメモリ領域にアクセスできない。
プロセスは、割り当てられた仮想メモリ空間内であれば、自由にメモリを使用できる。

処理フロー

  1. ユーザーがターミナルにコマンドを入力する。
  2. シェルが入力されたコマンドを解釈する。
  3. シェルがカーネルに fork() システムコールを発行し、子プロセスを生成する(外部コマンドの場合)。
  4. 子プロセスがカーネルに exec() システムコールを発行し、実行するプログラムを置き換える(外部コマンドの場合)。
  5. カーネルがプログラムの実行を制御する。
  6. プログラムがカーネルにシステムコールを発行し、必要なハードウェア資源にアクセスする。
  7. カーネルがプログラムの実行結果を標準出力に出力する。
  8. 子プロセスがカーネルに exit() システムコールを発行して終了する(外部コマンドの場合)。
  9. カーネルが子プロセスの終了処理を行い、シェルに終了ステータスを通知する(外部コマンドの場合)。
  10. シェルが子プロセスの終了を待機し、次のコマンド入力を受け付ける。

親プロセスで直接 exec() システムコールをカーネルに発行しない理由・子プロセスでコマンドを実行する理由

親プロセスであるシェルが直接 exec() システムコールをカーネルに発行してプログラムを実行することも技術的には可能だが、外部コマンド実行時に子プロセスを生成する理由は、主に以下の2点にある。

① シェルの継続的な動作の確保
シェルは、ユーザーからのコマンド入力を受け付け、実行結果を表示する役割を担っている。
もし親プロセスであるシェルが直接 exec() システムコールを実行すると、シェル自体が外部コマンドのプログラムに置き換わってしまう。
つまり、外部コマンドの実行が終了するまで、シェルは次のコマンド入力を受け付けられなくなり、ユーザーはターミナルを操作できなくなる。
子プロセスを生成することで、シェルは外部コマンドの実行とは独立して動作し、ユーザーはコマンド実行中もターミナルを操作できる。

② 環境の分離
外部コマンドは、シェルとは異なる環境で実行される必要がある場合がある。
例えば、外部コマンドが環境変数を変更したり、ファイルを操作したりする場合、シェルの環境に影響を与えないようにする必要がある。
子プロセスは、親プロセスから環境を引き継ぐが、独立したメモリ空間を持つため、外部コマンドの動作がシェルの環境に影響を与えない。
これにより、外部コマンドの実行による予期せぬ副作用を防ぐことができる。

実行ファイルの種類

・実行ファイルは、コンパイルされたバイナリファイルだけでなく、シェルスクリプトなどのスクリプトファイルの場合もある。
・スクリプトファイルの場合、ファイルの先頭にどのインタプリタ(例えば、#!/bin/bash)で実行するかを指定する必要がある。

PATHの設定

PATH環境変数は、ユーザーのホームディレクトリにある.bashrcや.zshrcなどの設定ファイルで設定できる。これにより、よく使う実行ファイルがあるディレクトリをPATHに追加することで、毎回フルパスを入力しなくてもコマンドを実行できるようになる。

ハッシュ

シェルは、一度検索したコマンドのパスをハッシュテーブルに保存し、次回以降の検索を高速化する。

ポイント

①シェルはファイルシステムを直接操作しない。
 シェルは PATH を参照 して実行ファイルの場所を探し、OS(カーネル)に実行を依頼する。
②ファイルシステムは「どこに何があるか」を管理するだけ。
 実行可能ファイルが PATH 内のどこかにあれば、OSがそれを実行する。
③カーネルがプログラムをロード・実行する。
 シェルは指示を出すだけで、実際のプログラム実行はカーネルが担当。


https://www.reqtc.com/blog/shell-kernel-bash.html より画像引用

システムコール


https://blog.framinal.life/entry/2020/04/22/063346 より画像引用

mabomabo

ファイルシステム

Linuxカーネルのファイルシステム全体像

https://monoist.itmedia.co.jp/mn/articles/1009/01/news108.html より画像引用

解説

ファイルシステムはユーザ(アプリ、プロセス)がディスクにデータを書き込む時に使われる面倒なことを引き受けてくれる仕組み。
OSが提供する機能の一つで、データをファイルやディレクトリ(フォルダ)として管理するための仕組み。
本来であればディスク(物理ストレージ)に書き込む時には「どのブロック(位置)に何Byte書き込むのか」を規定しなければなりませんが、利用する時にいちいち宣言するのは面倒なのでファイルシステムを介することでその負担を排除している。
ファイルシステムはユーザにとって意味のあるデータを名前や位置、サイズなどのメタデータをくっつけてファイルとして管理している。
ファイルシステムは、共通ファイルシステム(VFS)個別ファイルシステム(xfs/ext4など) の2つに分類できる。


※参照https://blog.framinal.life/entry/2020/04/21/193030 より画像引用、解説一部編集

ファイルシステムの基礎

そもそもデータを扱うということはどういうことなのでしょうか。通常OSを操作する上において、データを操作するということはファイルを操作することとほぼ同等の意味を持つかと思います。このため通常はデータが物理的にどのように格納されているかを意識する必要もなく、逆に意識できない作りになっています。これはOSの機能であるデータの抽象化によってもたらされる結果です。実際に物理的な記憶装置に格納されているデータを素で扱おうとすると、 HDDのどこのセクタのどの部分とどの部分を取り出して、データをメモリ上に読み込み、メモリに格納できないものは後からまた読む・・・といった大変面倒なことをする必要があります。現在のHDDの容量を考えてみると、何百ギガバイト(テラになりつつありますが・・・)という巨大なデータを格納できるような物体です。その中に入っている何かのデータを自力で探しだし、利用することは人間が行う作業として成立しないものだともいえます。このような物体に存在するデータを人間にわかりやすいファイルというものに抽象化、可視化し、データを永続的に管理しやすくするという役目を持つのがファイルシステムの基本的な考え方です。

ファイルシステムにはほかにもキャッシュメモリを利用して効果的にHDDなどの二次記憶装置を使うという機能も含まれており、Linuxではこの機能によって大きなファイルでも高速にアクセスすることが可能になっています。このようにファイルシステムは単にデータを扱いやすく管理するだけではなくH/Wリソースを効率よく利用するための機能も含まれています。

https://lpi.or.jp/lpic_all/linux/intro/intro10.shtml より解説引用

VFS(Virtual File System)

Linuxでは全てをファイルとして扱うようになっています。これは通常のデータファイルだけではなく、HDD、CD-ROM、マウスなど様々なデバイスもファイルとして扱う仕組みになっています。この仕組みを提供するのがVFSという仮想的なファイルシステムです。VFSは下位の物理的な媒体を抽象化し、データ、デバイスを含む全てのコンピュータリソースに対して統一的なファイルアクセスという入出力インターフェイスを提供します。これによりリソースの差異を気にすることなく、様々な対象に対して統一のアクセスを行うことができます。
さらにVFSにはファイルシステムの抽象化という役割もあり、これによってことなる複数のファイルシステムに対して透過的にアクセスすることが可能になっており、ファイルシステムの種類を意識せずに利用することができます。VFSは、プログラムからのファイルシステムの操作を固有のファイルシステムの操作に変換します。このためユーザが実行するプログラムはファイルシステムの差異を意識する必要がなく、統一的なアクセス方法で実際にはことなるファイルシステムにアクセスできます。


https://lpi.or.jp/lpic_all/linux/intro/intro10.shtml より画像・解説引用

具体的な役割

データの保存と読み取り
ファイルやディレクトリの階層構造の管理
ファイルのアクセス権限の管理
ディスク領域の効率的な利用

OSとファイルシステムの関係

・OSは、ファイルシステムを介してハードウェア(HDDやSSDなど)とアプリケーションの間の橋渡しをする。
・OSは環境変数を介して、ファイルシステムへのアクセスを制御する。

具体的な役割

抽象化
OSは、物理的なストレージデバイスを抽象化し、ファイルやディレクトリとして扱えるようにする。

アクセス制御
OSは、ユーザーやアプリケーションがファイルにアクセスする際の権限を管理する。

パスの解決
OSは、ファイルやディレクトリへのパスを解決し、正しい場所にアクセスできるようにする。

mabomabo

システムコール

ユーザー空間のプログラムがカーネル空間の機能を利用するためのインターフェース。
カーネルは、ハードウェアやシステムリソースを管理するための特権的な操作を行なうが、ユーザー空間のプログラムは直接これらの操作を行うことができない。そこで、システムコールを使ってカーネルに依頼し、必要な操作を行なってもらう。


https://ascii.jp/elem/000/001/267/1267477/ より画像引用


https://qiita.com/fujifuji1414/items/5373f3da51465c82d0d4 より画像引用

システムコールの具体的な流れ

(例)ls コマンド

(1) ユーザーがコマンドを入力

ユーザーがシェルに ls と入力する。

(2) シェルがコマンドを解釈

シェルは、入力された ls を解釈する。
ls は外部コマンド(シェルの組み込みコマンドではなく、別の実行ファイル)であることを認識する。

(3) 環境変数 PATH を参照

シェルは、ls コマンドの実行ファイルの場所を探すために、環境変数 PATH を参照する。
PATH は、実行ファイルが保存されているディレクトリのリスト。
(例)PATH=/usr/bin:/usr/local/bin
・シェルは、/usr/bin と /usr/local/bin ディレクトリを順に検索する。

(4) fork() システムコールで新しいプロセスを生成

シェルは、fork() システムコールを使って新しいプロセスを生成する。
この新しいプロセスは、親プロセス(シェル)の環境変数や設定を継承します。
新しいプロセスは、親プロセスの環境変数(例: PATH)をそのまま引き継ぐ。

(5) exec() システムコールで ls を実行

新しいプロセスは、exec() システムコールを使って ls コマンドの実行ファイルをメモリにロードし、ls プログラムを実行する。
exec() は、PATH 環境変数を参照して ls の実行ファイルを検索する。
(例)/usr/bin/ls が見つかると、そのプログラムを実行する。


http://shivammitra.com/operating system/fork-exec-wait-in-operating-system/# より画像引用

(6) ls がシステムコールを発行

ls プログラムは、ディレクトリ内のファイル情報を取得するために、以下のようなシステムコールを発行する。
・open():ディレクトリを開く。
・read():ディレクトリ内のエントリ(ファイルやサブディレクトリ)を読み取る。
・stat():ファイルの詳細情報(サイズ、パーミッションなど)を取得する。

(7) カーネルがシステムコールを処理

カーネルは、ls が発行したシステムコールを受け取り、以下のような処理を行なう。
・ファイルシステムにアクセスしてディレクトリ内の情報を取得する。
・ハードウェア(ディスクなど)とやり取りしてデータを読み取る。
・取得した情報を ls プログラムに返す。

(8) ls が結果を表示

ls プログラムは、カーネルから受け取った情報を整形して、標準出力(通常はターミナル)に表示する。

(9) プロセスの終了

ls の実行が終了すると、プロセスは終了ステータスを親プロセス(シェル)に返す。
シェルは、このステータスを受け取って次のコマンド入力を待つ。
シェルは、wait() システムコールを使って子プロセスの終了を待ち、終了ステータスを受け取る。

まとめ

①シェルが PATH を参照
 外部コマンドの実行ファイルを探す。
②fork() で子プロセスを生成
 子プロセスは親プロセスの環境変数を引き継ぐ。
③子プロセスが exec() を呼び出す
 外部コマンドの実行ファイルをメモリにロードし、プログラムを実行する。
④外部コマンドがシステムコールを発行
 カーネルに処理を依頼し、結果を受け取る。
⑤外部コマンドが結果を標準出力に表示
 シェルは直接関与しない。
⑥子プロセスが終了
 終了ステータスを親プロセス(シェル)に通知する。
⑦シェルが wait() で終了を待つ
 終了ステータスを受け取り、次のコマンドを待機する。

mabomabo

bashの設定ファイル

ログインシェル・非ログインシェル

ログインシェル

ユーザーがシステムにログイン(コンソールやターミナルで直接ログインするときや、ssh でリモートログインするときなど)するときに起動される。

設定ファイルの読み込み


https://oxynotes.com/?p=5418 より画像引用

/etc/profile

・システム全体の シェル の設定ファイル。
・すべてのユーザーに適用され、すべてのシェル(Bash、sh、zshなど)に適用される。

~/.bash_profile(または ~/.bash_login~/.profile

・ユーザーごとのログインシェル用設定ファイル。
・ログインしたときだけに読み込まれる。
・ログインシェル固有の設定(環境変数の設定など)を記述する。
・ログインしたときに一度だけ実行したい設定を記述する。
(例)環境変数の設定や、ログイン時に実行したいコマンドなど
・多くの場合、このファイル内で ~/.bashrc を読み込むように記述されている。

~/.bashrc

・ユーザーごとの非ログインシェル用設定ファイル。~/.bash_profile から読み込まれる。
・bash を起動するたびに読み込まれる。
→ 新しいシェルセッションが開始されるたびに読み込まれる設定ファイル
・シェルを起動するたびに実行したい設定を記述する。
・ログインシェルと非ログインシェルの両方で共通の設定を記述できる。
・ユーザー独自のカスタマイズはこのファイルで記述する。

非ログインシェル

ログイン後(ログイン後にターミナルを新しく開くときや、既存のシェルから新しいシェルを起動するときなど)に新しいシェルを起動するときに実行される。

設定ファイルの読み込み

/etc/bash.bashrc

・システム全体の Bashシェル の設定ファイル
・Bashシェルのみに適用される。

~/.bashrc

・ユーザーごとのBash設定ファイル
・特定のユーザーのみに適用される。
・シェルを起動するたびに実行したい設定を記述する。
・ユーザー独自のカスタマイズはこのファイルで記述する。
(例)エイリアスの設定や、プロンプトのカスタマイズなど

設定ファイルの変更時の注意点

◎最初の状態の~/.bashrc ファイルはコピーを取っておき、バックアップを取っておくこと

◎設定を行なうシェルとは別にもう一つのシェルを起動しておくこと

こうすることで、もし間違えてログインできなくなった場合でも、別に起動しておいたシェルから復旧作業ができる。
(例)①Vimで誤った記述を削除する ②元のバックアップファイルで現在の ~/.bashrc を上書きする、などの方法が取れる。

mabomabo

ジョブ・プロセス・スレッド

ジョブ

・OS(特にバッチ処理環境)やシェルによって管理される、一連の処理のまとまり。
・ジョブは「何を実行するか」の指示であり、プロセスやスレッドは実際に作業をするもの。
・シェルやOSに対する命令(タスクの依頼)

(例)シェルスクリプトやバッチジョブ
・シェル(Bashなど)を介して実行される場合:ジョブはシェルが管理
・OSのジョブスケジューラ(cronやsystemd)を介する場合:OSが管理
・シェルでコマンドを実行すると、新しいプロセスが生成されるが、それをシェルは「ジョブ」として管理できる。

プロセス

・OSが直接管理する個々の実行単位。
・1つの独立した仕事(プログラムの実行単位)

スレッド

・プロセス内の個々のタスク
※プロセスは独立しているが、スレッドはプロセスの中で協力して動く。
→スレッドは同じメモリ空間を共有しているので、データの受け渡しが早いが、干渉しやすい。どこかでミスが発生すると、全体に影響が出る。

mabomabo

ファイルパーミッション

Linuxで扱われるファイルは、すべてに所有者(オーナー)が設定されている。
ファイルのオーナーは、ファイルへのアクセス権限を自由に設定できる。
ls-lオプションをつけて詳細表示することで、ファイルのオーナーを確認できる。

グループ

ユーザをまとめた集まりのこと
ユーザは同時にいくつものグループに所属できるが、最低1つのグループに属してないといけない。

自分が現在どのグループに属しているかを確認する方法

$ groups

ファイルのパーミッション

パーミッション:1つ1つのファイルには「誰に、どのような操作を許可するか」という権限を規定する情報が設定されている。

3文字ごとの1つのブロックになっている。
・オーナー
・グループ
・その他のユーザ

パーミッションの記号と意味

記号 意味
r 読み取り(read)
w 書き込み(write)
x 実行(execute)

lsコマンドの-lオプションでは、以下のように表示される
・操作が許可されているとき「r」「w」「x」
・操作が許可されていないとき「-」

ディレクトリのパーミッション

まとめ

パーミッション ファイルの場合 ディレクトリの場合
r ファイルの内容を読み込み可能(cat) ファイル一覧を表示(ls)
w ファイルの内容を変更可能 ファイルを作成・削除・名前変更可能
x ファイルを実行可能(./script.sh) ディレクトリ(cd)に移動可能

※ファイルの削除ができるかどうかはディレクトリのパーミッションで決まり、ファイル自身のパーミッションは関係ない。

mabomabo

chmodコマンド:ファイルモードを変更する

シンボルモード(相対的指定)

「誰に、どのような権限を追加(もしくは禁止)するのか」を表す
パーミッションの一部だけを変更したいときに便利

chmod [ugoa] [+-=] [rwx] <ファイル名>

// 複数のユーザをまとめて指定
// 例:グループとその他を read-only に設定
$ chmod go=r file.txt
記号 意味
u オーナー
g グループ
o その他のユーザ
a ugoすべて

chmodコマンドの演算子

記号 意味
+ 権限を追加する
- 権限を禁止する
= 指定した権限と等しくする

数値モード(絶対的指定)

元のパーミッションにかかわらず、新しいパーミッションの値へと変更する。
足した値を「オーナー」「グループ」「その他のユーザ」の順に3つ並べて指定する。
この3桁の数字がパーミッションを指定するための値。

chmod <8進数の数字> <ファイル名>

数値モードでのパーミッションの数値

意味 数字
読み取り(r) 4
書き込み(w) 2
実行(x) 1
mabomabo

スーパーユーザ

管理者権限を持つ特別なユーザ
ユーザ名が root であることから、root ユーザと呼ばれることもある。
ファイルのパーミッションの影響を受けず、あらゆる操作を許可された強力な権限を持つ。

※強力な権限ゆえに、操作を誤るとシステム自体を破壊してしまうこともあるため慎重に取り扱う必要がある。

通常、一般ユーザでログインして操作し、必要な時だけスーパーユーザとして作業する

スーパーユーザの利用を最小限にとどめることが大切

su コマンド:ユーザを変更する

一時的に別のユーザになるためのコマンド
主にスーパーユーザになるために使用される。
exit コマンドを明示的に終了するまで、スーパーユーザの権限が継続する。
※ディストリビューションの種類や設定によっては、このコマンドでスーパーユーザになれないこともある。

オプションをつけない su コマンドでユーザを切り替えると、環境変数やカレントディレクトリなどの現在の環境を維持したままユーザだけ切り替わる

su -(ハイフン)

スーパーユーザの環境に初期化されてユーザが切り替わる

sudo コマンド:コマンドを別のユーザとして実行する

一つのコマンドだけをスーパーユーザ権限で実行する。
一般ユーザにスーパーユーザの権限を与えるコマンド。
コマンドが終了すれば、元の一般ユーザの状態に自動的に戻る。
別のユーザとしてコマンドを実行するために使用される。
sudo コマンドを実行すると、現在ログインしているユーザのパスワードを求められる。
必要なときだけスーパーユーザとしてコマンドを実行する。

ユーザに sudo を許可するかどうかは、/etc/sudoers ファイルで管理されている。

sudoers ファイル

<ユーザ><マシン>=(<権限>)<コマンド>の形式で記述する。
<ユーザ> の部分は、直接ユーザ名を書くか、%<グループ名>の形でグループを指定する。

wheel, admin, sudo というグループ名が使われていることもある。
あるユーザにsudo が許可されていない場合、 スーパーユーザが /etc/sudoers ファイルに追記して権限を追加することができる。

visudo コマンド:sudoers ファイルを編集する

sudo の設定を行なう場合、 /etc/sudoers ファイルを直接テキストエディタを開いて編集してはいけない。
書き方を誤ってしまうと、sudo が動作せず、どのユーザも sudo を使えなくなってしまう。

mabomabo

プロセス


http://ash.jp/linux/unyo/06.htm より画像引用

・メモリ上で実行状態にあるプログラム
・OSが直接管理する個々の実行単位。
・1つの独立した仕事(プログラムの実行単位)。
・Linuxカーネルから見た処理の単位。
・システム全体で一意のプロセスIDを持つ。
・Linuxでプロセスが新しく作られるときは、無から発生するのではなく、すでに存在している別のプロセスを元に作成されるというモデルをとっている(親子関係をとる)。
・コマンドをパイプで繋いだ場合、コマンドごとに生成される。

https://howahowablog.com/process-and-job-1/ より画像引用

ジョブ・プロセス・スレッド

https://itmanabi.com/job_task/ より画像引用

ps コマンド:プロセスの表示

現在動作しているプロセスを表示する。
・PID:プロセスID
※プロセスIDはプロセスが起動してから終了するまで変化しない。
・CMD:実行されているコマンド
・TTY:ターミナル

オプション形式

UNIXオプション:ハイフン付きでオプションを指定する

BSDオプション:ハイフンなしでオプションを指定する

※現在の主流

Linuxではマルチタスク機能により、さまざまなプロセスが同時に動作している

BSDオプション:よく使用される ps コマンドのオプション組み合わせ

オプション 意味
x psコマンドを実行したユーザのプロセスをすべてを表示
ux psコマンドを実行したユーザのプロセスすべてを、詳細情報を合わせて表示
ax すべてのユーザのプロセスを表示
aux すべてのユーザのプロセスを、詳細情報を合わせて表示
auxww auxオプションで、コマンドラインが長くターミナルの右端で切れてしまう際に、、表示幅を制限せずすべて表示

プロセスとファイルディスクリプタ

https://curtaincall.weblike.jp/portfolio-unix/api.html より画像引用

スレッド

・プロセス内の個々のタスク
※プロセスは独立しているが、スレッドはプロセスの中で協力して動く。
→スレッドは同じメモリ空間を共有しているので、データの受け渡しが早いが、干渉しやすい。どこかでミスが発生すると、全体に影響が出る。

mabomabo

ターミナルに接続していないプロセス

デーモン(Daemon)やバックグラウンドプロセスとして動作するプロセスのこと。
これらのプロセスは、ユーザーがターミナルから直接操作するのではなく、システムや他のプログラムの要求に応じて自動的に動作する。

ターミナルに接続していないプロセスの特徴

バックグラウンドで動作

ターミナルに表示されず、裏でひっそりと動作します。
ユーザーが気づかないうちに、システムの重要な処理を行っています。

ターミナルからの入出力がない

標準入力(stdin)、標準出力(stdout)、標準エラー出力(stderr)がターミナルに接続されていません。
ログファイルやシステムログに出力されることが多いです。

システム起動時に自動的に起動
多くの場合、システムの起動時に自動的に起動され、システムが終了するまで動作し続けます。

ターミナルに接続していないプロセスの例

デーモンプロセス
・Webサーバー(例: Apache, Nginx)
・データベースサーバー(例: MySQL, PostgreSQL)
・ネットワークサービス(例: SSHデーモン sshd)

バックグラウンドで実行されるユーザープロセス
・ユーザーがバックグラウンドで起動したプロセス(例: ./myprogram &)
・スクリプトやアプリケーションがバックグラウンドで実行するプロセス

mabomabo

ジョブ

・OS(特にバッチ処理環境)やシェルによって管理される、一連の処理のまとまり。
・ジョブは「何を実行するか」の指示であり、プロセスやスレッドは実際に作業をするもの。
・シェルやOSに対する命令(タスクの依頼)
・シェルから見た処理の単位。
・シェルごとに処理番号を持つ。
・コマンドをパイプで繋いだ場合、コマンドライン全体で一つ。

(例)シェルスクリプトやバッチジョブ
・シェル(Bashなど)を介して実行される場合:ジョブはシェルが管理
・OSのジョブスケジューラ(cronやsystemd)を介する場合:OSが管理
・シェルでコマンドを実行すると、新しいプロセスが生成されるが、それをシェルは「ジョブ」として管理できる。

コマンドの一時停止

Ctrl + z :コマンドを一時停止 ※再開することができる
jobs:ジョブの一覧を表示
・先頭の[1]や[2]はジョブ番号を表す。プロセスIDも表示したい場合はjobs -l-lをつける。


https://www.infraexpert.com/infra/linux21.html より画像引用

fg コマンド:ジョブをフォアグランドにする

ユーザ入力を受け付けるジョブの状態
指定したジョブ番号をキーボードで操作で状態に戻る
※復帰したときには、スクロール位置など停止状態にする直前の状態が復元される
※ジョブ番号を省略すると、カレントジョブがフォアグランドになる。

fg %<ジョブ番号>

bg コマンド:ジョブをバックグラウンドにする

ユーザが対話的に操作できないジョブの状態
指定したジョブ番号をキーボードで操作で状態に戻る
末尾の&:ジョブがバックグラウンドの状態であることを表す。
はじめからジョブをバックグラウンドで実行したいときは、コマンドラインの末尾に&を追加する
Ctrl + zで停止してから、bgコマンドでバックグラウンドにする、という操作は不要

bg %<ジョブ番号>

ジョブの状態遷移

フォアグラウンド

ユーザが対話的に操作しながら処理が実行されている状態

バックグラウンド

ユーザが対話的に操作せずに処理が実行されている状態

停止

処理を一時的に中断している状態

ジョブ・プロセスの終了

ジョブの終了

Ctrl + c:フォアグラウンドジョブを終了する
※バックグラウンドジョブまたは停止の状態にあるジョブはキーボード入力を受け付けていないため、Ctrl + cを入力することができないため、ジョブ番号を指定して kill コマンドを使う。

// ジョブの終了
kill %<ジョブ番号>

// プロセスの終了
kill <プロセスID>

プロセスの終了

プロセスの場合は、%をつけずにプロセスIDをそのまま指定する。
※プロセスを終了できるのはその実行ユーザのみとなっている。

kill コマンド:シグナルの送信

「シグナルを送信する」コマンド
シグナル:プロセスに送信される信号
実行中のプロセスに対してシグナルを送ることで、プロセス間の通信を行なうことができる。
※ KILLシグナルは最後の手段として使用すること
→終了処理をせずに強制的にプロセスが終了してしまうため

kill -<シグナル名>

シグナル名を省略すると、デフォルト値としてTERMというシグナルを送信する。
ジョブは受け取ったシグナルを元に操作を実行している。
kill -l:システムで利用可能なシグナル一覧の表示
シグナル名は先頭に"SIG"という接頭辞をつけて表示する。

◎kill コマンドでプロセスを終了させる場合は、始めにTERMシグナルを試し、それでもうまく終了できないときだけKILLシグナルを使用すること


https://www.infra-linux.com/linux-cmd-menu2/job-state-transitions/ より画像引用

mabomabo

標準入力・標準出力・標準エラー出力


https://xtech.nikkei.com/atcl/nxt/column/18/02297/121500004/ より画像引用

標準入力(stdin)

プログラムの標準的な入力
通常はキーボードが使われる。ファイルの場合もある。

標準出力(stdout)

プログラムの標準的な出力
通常は端末ディスプレイが使われる。

標準エラー出力(stderr)

プログラムのエラーメッセージを出力するための標準的な出力
通常は端末ディスプレイが使われる。

※『新しいLinuxの教科書 第2版』より、画像引用

リダイレクト

標準入出力先を変更する機能のこと

入力リダイレクト:キーボードの代わりにファイルを標準入力につなぐこと

何かしらのコマンド作る際には、入力データを標準入力から読み込む仕組みを備えるようにすること
→より汎用性が高く、他のプログラムと連携しやすくなる。

標準出力のリダイレクト
コマンドの実行結果を画面に表示するのではなくファイルに保存したい場合に使用する。
※リダイレクト先のファイルは自動的に作成されるため、事前に touch コマンドなどでファイルをつくっておく必要がない。

標準出力と標準エラー出力は別々のチャネルになっている
標準出力をファイルにリダイレクトしてもエラーメッセージが画面に出力されるのは、標準エラー出力がリダイレクトされない限り、デフォルトで画面に出力される設定になっているから。

標準出力と標準エラー出力をまとめる
標準出力をリダイレクトした後ろに、2>&1 と書く。

Linuxの内部では標準入出力が数値として管理されている。
標準入出力の数値

入出力チャネル 数値
標準入力 0
標準出力 1
標準エラー出力 2

リダイレクトによる上書き

> で標準出力をリダイレクトする際に、指定したファイル名と同一のファイル名が存在する場合は、上書きされて元のファイルが失われる

>>:ファイルの末尾に追記する ※上書きしないため、元のファイルの内容が失われない

② シェルオプション noclobber という値を set コマンドで設定する

リダイレクトの記法

記号 意味
< FILE 入力リダイレクト
標準入力の入力元をFILEに変更する
> FILE 標準出力のリダイレクト
標準出力の出力先をFILEに変更する
>> FILE 標準出力の出力をFILEの末尾に追記する
2> FILE 標準エラー出力のリダイレクト
標準エラー出力の出力先をFILEに変更する
2>> FILE 標準エラー出力の出力をFILEの末尾に追記する
> FILE 2>&1 標準出力と標準エラー出力の出力先を、共にFILEに変更する

/dev/null


https://www.digitalocean.com/community/tutorials/dev-null-in-linux より画像引用

UnixやLinuxシステムにおいて特殊なファイルとして存在し、「ビットバケット」や「ブラックホール」とも呼ばれる。その主な役割は、不要なデータを破棄すること。
・入力元として指定しても何も返さない
・出力先として指定しても、書き込んだデータはどこにも保存されずに消えてなくなる
・/dev/null に書き込まれたデータはすべて破棄される。
・/dev/null から読み取ろうとすると、常にEOF(End of File)が返される。

使い方例
① 標準入力を /dev/null にリダイレクト

書式
コマンド < /dev/null

・標準入力(stdin)が /dev/null にリダイレクトされ、プログラムがキーボードからの入力を待たなくなる。
・プログラムが入力を受け取ろうとしても、何も得られない(EOFが返される)
バックグラウンド実行時
バックグラウンドで実行するプログラムが標準入力を必要としない場合、/dev/null にリダイレクトすることで、不要な入力待ちを防ぐ。
自動化スクリプト
ユーザーからの入力を必要としないスクリプトを実行する場合、標準入力を /dev/null にリダイレクトする。

② 標準出力を /dev/null にリダイレクト

書式
コマンド > /dev/null

・標準出力(stdout)が /dev/null にリダイレクトされ、プログラムの出力が画面に表示されなくなる。
・出力データはすべて破棄される。
出力を無視したい場合
プログラムの出力が不要な場合(例: ログが大量に出力される場合)に使用する。
エラーのみを確認したい場合
標準出力を破棄し、標準エラー出力のみを表示する場合。

③ 標準エラー出力を /dev/null にリダイレクト

書式
コマンド 2> /dev/null

・標準エラー出力(stderr)が /dev/null にリダイレクトされ、エラーメッセージが表示されなくなる。
・エラーメッセージはすべて破棄される。
エラーメッセージを無視したい場合
エラーメッセージが不要な場合や、エラーが発生しても無視したい場合に使用する。
正常な出力のみを確認したい場合
標準エラー出力を破棄し、標準出力のみを表示する場合。

mabomabo

パイプライン |


https://xtech.nikkei.com/atcl/nxt/column/18/02297/121500004/ より画像引用

コマンドの標準出力を別のコマンドの標準入力につなぐ機能
標準出力に結果を表示するコマンドはなんでもパイプで less コマンドにつなぐことができる。
パイプラインは|で好きなだけいくつでもつなげることができる。
パイプラインは標準出力だけを次のコマンドに送る。
パイプを使用している場合、ファイルの内容を直接変更しているのではなく、データの流れを操作している

標準エラー出力もまとめてパイプラインに送りたいときは、2>&1という記法を利用し、標準エラー出力を標準出力へリダイレクトする。


※『新しいLinuxの教科書 第2版』より、画像引用

コマンドライン履歴
bash に入力されたコマンドラインは、~/.bash_history というファイルに履歴として保存される。
historyコマンド

mabomabo

フィルタ


https://software.fujitsu.com/jp/manual/manualfiles/M070042/J2X06060/05Z200/xlmv05/xlmv0172.html より画像引用

標準入力を入力として受け取り、標準出力に出力するコマンド
フィルタコマンドとは、標準入力からテキストを受け取り、何らかの処理を施して標準出力に出力するコマンドのこと
ファイル名を引数として受け取ると、そのファイルの内容を読み込み、テキストデータとして処理する。
ファイル全体を一度に読み込むか、行単位で読み込むかはコマンドによって異なるが、結果としてファイル全体のテキストに対してフィルタリング処理が行われる。「ファイル」という単位で処理を行なう。

代表的なフィルタコマンド

コマンド 役割
cat 入力をそのまま出力する
head 先頭の部分を表示する
tail 末尾の部分を表示する
grep 指定した検索パターンに一致する行だけ表示する
sort 順番に並び替える
uniq 重複した行を取り除く
tac 逆順に表示する
wc 行数やバイト数を出力する

du コマンド:指定したファイルやディレクトリの使用容量を表示 ~disc usage~

du [オプション] [ファイル / ディレクトリ]

du コマンドの主要なオプション
-b オプション:引数で指定されたファイルのサイズをバイト単位で表示

-a (--all): 全てのファイルとディレクトリのディスク使用量を表示
デフォルトではディレクトリのみ表示されるが、このオプションを使うとファイルも表示される。

-h (--human-readable): 人間が読みやすい形式で表示
キロバイト (KB)、メガバイト (MB)、ギガバイト (GB) などの単位を自動的に選択して表示

-s (--summarize): 合計サイズのみを表示
指定したディレクトリの合計サイズのみを表示

-c (--total): 合計サイズを最後に表示
表示された全てのファイルやディレクトリの合計サイズを最後に表示

-d (--max-depth=N): 指定した深さまでのディレクトリを表示
N は数字で、表示するディレクトリの深さを指定する
(例)du -d 1 (カレントディレクトリから1階層下のディレクトリまで表示)

-B (--block-size=SIZE): 指定したサイズ単位で表示
SIZE には、K, M, G などの単位を指定できる
(例)du -B M (メガバイト単位で表示)

sort コマンド:(デフォルト)辞書順に並び替え

-n オプション:数値順でソート

mabomabo

テキスト処理

● wc コマンド:バイト数・単語数・行数を数える


※『新しいLinuxの教科書 第2版』より画像引用

オプション

-l:行数を表示
-w:単語数を表示
-c:バイト数を表示

フィルタを使う際に標準入力から読み取ることを明示的に指定したい場合は - を入力ファイル名として利用する。

● sort コマンド:行を並べ替える

ソート:一定の規則に基づいて行を並び替えること
sort コマンドの デフォルトでは辞書順・アルファベット順に行を並び替える
フィールド:各項目

よく使用されるオプション
-k オプション:フィールド番号の指定
-n オプション:数値順にソート
-r オプション:逆順にソート

※sort コマンドはASCIIコード順にソートするため、純粋な辞書順にはならない
※ASCIIコードは歴史的な理由から、アルファベットは大文字の方が番号が小さく、小文字の方が大きい番号が割り当てられている。

-n オプション:数値順にソート

文字列を数値とみなして並び変えるためのオプション

-r オプション:逆順にソート

逆順にソートするためのオプション

-rn :ファイルサイズの大きい順に表示することができる**

逆順ソートと数値ソートの組み合わせ

● uniq コマンド:重複行を取り除く

同じ内容の行が連続している場合にのみ重複を取り除く
※重複行が連続していない場合には取り除かれない。
◎一旦 sort コマンドを使って対象ファイルの内容を並び替えておくと、ファイル全体から重複行を取り除くことができる

-u オプション
uniq コマンドを使わずに重複行を取り除くことができる

$ sort -u file3

/etc/passwd

https://infosecwriteups.com/what-is-etc-passwd-group-shadow-file-in-linux-bd7b28f353f3 より画像引用

mabomabo

テキスト処理

● cut コマンド:入力の一部を切り出す

元のデータから特定の部分だけを取り出したいときに便利なコマンド

書式
cut -d <区切り文字> -f <フィールド> [<ファイル名>]

<区切り文字> で指定した文字で入力行を分割し、その中の <フィールド番号> で指定したフィールドだけを出力する。
※ -d オプションをつけずに区切り文字を指定しない場合は、デフォルト値としてタブが区切り文字とみなされる。

-d:delimiter(デリミタ)の略。区切り文字を指定。
-f:fields(フィールド)の略。切り出すフィールドを指定。

● tr コマンド:文字を変換・削除する

trコマンドは1文字単位の文字置換
※文字列を置換したときは、sedコマンドやawkコマンドを利用する。

tr <置換前の文字> <置換後の文字>


※『新しいLinuxの教科書 第2版』より、画像引用

置換文字に-(ハイフン)を使用することで文字範囲を指定することができる。
(例)a-z A-Z:小文字から大文字に変換

ファイル指定の注意

trコマンドは、ファイルから直接読み込むことができない
→ テキストファイルの内容に対してtrコマンドを実行したい場合は、ファイルをcat してパイプで渡すか、入力リダイレクトを使用する。

解説
trコマンドは、文字単位での置換や削除に特化しており、ファイル全体を処理するというよりは、ストリーム処理に特化している。そのため、他のフィルタコマンドとは異なり、ファイル名を直接引数として受け取るのではなく、標準入力を処理するように設計されている。
※ほとんどのフィルタコマンドは、ファイル名を指定しない場合に標準入力からテキストを読み込み、処理を行なう。
※trコマンドは例外的に、標準入力からの処理に特化したコマンド。
→ファイル名を直接引数として受け取るのではなく、標準入力からのストリームデータを処理するように設計されている。そのため、ファイルの内容を処理するには、リダイレクト (<) やパイプ (|) を使用して、ファイルの内容を標準入力に渡す必要がある。

文字の削除

書式
tr -d <削除文字>

削除機能がよく使用されるのは、改行コードを取り除いて1行にしたいケース

● tail コマンド:末尾部分を表示する

オプションを指定しない場合、ファイルの末尾10行が表示される。

-n オプション:表示する行数を指定

ファイルへの追記の監視
ログの出力やデータ収集などで 常時追記されていくファイルを表示する際に、追記されるたびにその内容を表示してファイル監視をすることができる。
ファイルの内容が書き換えられると、その都度リアルタイムで表示される。

書式
tail -f <ファイル名>

Ctrl + cで tail コマンド終了

mabomabo

テキスト処理

● diff コマンド:差分を表示する

設定ファイルやプログラムのソースコードに対して、編集前と編集後の変更内容を確認するためによく使われる。

書式
dif [オプション] <比較元ファイル> <比較先ファイル>

変更コマンド:元ファイルからどの行をどのように変更したのかを示す


※『新しいLinuxの教科書 第2版』より、画像引用

変更範囲1 変更種別 変更範囲2の形式

※変更種別
a(Add):追加
c(Change):変更
d(Delete):削除

変更コマンド内の変更種別

記号 内容
<範囲1> a <範囲2> 1つ目のファイルの範囲1の後に、2つ目のファイルの範囲2の内容が追加された
<範囲1> c <範囲2> 1つ目のファイルの範囲1の箇所が、2つ目のファイルの範囲2の内容に変更された
<範囲1> d <範囲2> 1つ目のファイルの範囲1の箇所が削除された


※『新しいLinuxの教科書 第2版』より、画像引用

行の先頭にある<:1つ目のファイルにだけある行
行の先頭にある>:2つ目のファイルにだけある行

変更があった行だけ表示される。2つのファイルで共通する行は表示されない。
ファイル内で複数行を変更した場合には、それぞれの箇所が差分として表示される。

ハンク(hunk):それぞれの差分表示ひとかたまりのこと

※『新しいLinuxの教科書 第2版』より、画像引用

ユニファイド出力形式(Unified Format)

diff コマンドに-uオプションに指定する

https://www.miraclejob.com/recommend/detail?cd=3718 より画像引用

最初の2行に指定した2つのファイルのファイル名と更新日時が表示される。
・追加された行は先頭に+
・削除された行は先頭に- が表示される。
差分は変更があった行だけではなく、それらの前後何行かも合わせて表示される。


※『新しいLinuxの教科書 第2版』より、画像引用

@@から始まる行:その差分が元のファイルの何行目に対応しているのかを表す
@@ -<1つ目のファイルの変更開始行>, <変更行数> +<2つ目のファイルの変更開始行>, <変更行数> @@ という形式
※変更開始行:それぞれのファイルの中での行番号
※変更行数:各ハンク部分の行数(変更があった行だけでなくその前後も含む)

差分の使い方とパッチ

あるファイルを変更した内容を他の人に伝える際に、変更後のファイル全体を送るのではなく、diff コマンドで出力された差分だけ送ることもできる。
差分を受け取った側は、元のファイルと差分ファイルから、変更後のファイルを復元できる。
こうすることで、大きなファイルに修正を加えた場合でも、ファイル全体を共有しなくて済む。

パッチ:修正内容を共有する目的で使用する差分ファイル
diff コマンドで出力された差分は、patch コマンドでパッチを当てる(修正を適用する)ことができる。
・パッチを当てる際、元のファイルが変更されていて行番号がずれていると、エラーとなることがある。しかし、ユニファイド形式だと、前後の内容も含まれているため、元のファイルの行が多少ずれていてもパッチとして適用できる。
・差分を表現する形式としてユニファイド形式がよく使用される。

mabomabo

正規表現

grep コマンド:ファイルから文字列を検索する

<ファイル名> から <検索パターン> に一致する行を出力する
※「マッチする」:検索パターンに一致すること。
grep コマンドはマッチした部分だけではなく、マッチした行全体を表示する。

書式
grep [オプション] <検索パターン> <ファイル名>

・-n オプション:マッチした行の行番号を表示させる
検索したいパターンがファイルのどのあたりにあるのかを調べるときに便利
・-i オプション:大文字小文字を区別せずにマッチさせる
・-v オプション:マッチしなかった行を表示させる
ログファイルやデータファイルなどから、不要な値をもつ行を除いて表示したいときに便利

別のコマンドの結果を grep で検索するのもよく使われる手法。

正規表現

条件に合致する文字列集合を表現するための記法

※『新しいLinuxの教科書 第2版』より、画像引用

正規表現はシェルに正規表現を展開させ内容にするために、' '(シングルクォート)で囲んで指定する
メタ文字:正規表現で意味を持つ記号

文字にマッチするメタ文字

メタ文字 意味
. 任意の1文字
[ ] [ ]に含まれる、いずれかの1文字
[^ ] [ ]に含まれない、いずれかの1文字
\ 直後のメタ文字の意味を打ち消す
^ 行の先頭
$ 行の末尾
^$ 空行

.(ドット)そのものを検索したい場合は、\(バックスラッシュ)をつけてエスケープする。
エスケープ:メタ文字の直前に\を置くことでメタ文字の意味を打ち消すこと

[ ]:特定の文字を指定するメタ文字

-(ハイフン) を使うことで文字の範囲を指定できる
(例)[a-ZA-Z]:アルファベットの大文字小文字すべて

[^ ]:指定した文字以外をマッチさせる
(例)grep 'text[^13]' 「text1」「text3」以外の文字列
※Linuxにおいて ^が否定の意味を持つのは、正規表現の[ ]の中

位置にマッチするメタ文字

他のメタ文字と組み合わせて、マッチする箇所を指定するために利用する。
^ :行の先頭に指定した文字列がある行だけが表示される。
※行頭に置く

$ :行の末尾に指定した文字列がある行だけが表示される。
※行末に置く

^$ :空行にマッチ
grepコマンドの -v オプションを利用して^$にマッチしない行を出力すると、ファイルから空行だけを取り除いて表示することができる

繰り返しを指定するメタ文字

他の正規表現の後に置いて、直前の正規表現が一定回数以上繰り返されていることを意味する。
◎単独で使うのではなく、必ず後ろにくっついて置かれる。

*:0回以上の繰り返し
※「0回」その直前の文字が存在しなくてもいいということ

[指定文字]* という形で、直前のいずれかの文字が0回以上繰り返される文字列にマッチする。

.*:あらゆる文字列にマッチ。

mabomabo

拡張正規表現

使えるメタ文字を増やした正規表現
-E オプションを利用すると、拡張正規表現として解釈される。

Linuxで利用されているgrep(GNU grep)は独自拡張により、-E オプションをつけなくても、メタ文字に\記号をつけることで一部の拡張機能と同等のパターンを基本正規表現で利用することができる。
※拡張正規表現を使うときは、-E オプションを明示的につけて利用することが推奨される。

拡張正規表現による繰り返し回数の指定

基本正規表現 拡張正規表現 意味
* * 0回以上の繰り返し
なし + 1回以上の繰り返し
なし ? 0回または1回の繰り返し
\{m, n\} {m, n} m回以上n回以下の繰り返し
{m\} {m} ちょうどm回の繰り返し
\{m,\} {m,} m回以上の繰り返し
\(\) () グループ化する
なし ` `

+*に似ているが、0回を含まない。直前の文字が少なくとも1つは必要

ちょうどm回の繰り返しは、日本の郵便番号のチェックなどによく使われる。
(例)[0-9]{3}-[0-9]{4}

mabomabo

sed コマンド(ストリームエディタ)

sed (Stream Editer):非対話型エディタ

sed コマンドは編集結果を標準出力に出力するため、元のファイルを変更しない
sed コマンドはフィルタとして動作するため、編集対象ファイルの指定がない場合には標準入力から読み込まれる。
sed は非対話型でフィルタとして動作し編集を行なうため、決まったパターンの編集を行なうケースでは非常に効率よく作業することができる。

対話型エディタ

※『新しいLinuxの教科書 第2版』より、画像引用

対話型エディタ(例えば、Vim、Emacs、VS Codeなど)は、ファイルをバッファ(メモリ内にある一時データ保管場所)に読み込み、画面上で編集し、その結果をファイルに保存するという流れで動作する。また、バッファに読み込まれた内容は、画面上で即座に表示される。

非対話型エディタ

※『新しいLinuxの教科書 第2版』より、画像引用

動作の流れ

  1. シェルから編集のためのコマンドを引数として与えて、sed コマンドを実行する
  2. sed コマンドは編集対象のテキストに対して、与えられた編集コマンドに対応する編集操作を行なう
  3. 編集後のテキストを、sed コマンドが標準出力に出力する
mabomabo

sed コマンド(ストリームエディタ)

sed は編集結果を表示するだけ、元のファイルを上書きしない。
sed のコマンドはアドレスで指定された行のみに作用する。
アドレスを指定していない(省略した)場合は、コマンドはすべての行に作用する。
アドレスは行番号だけでなく、正規表現で書くこともできる。その際には、正規表現を/(スラッシュ)で囲む。
sed のアドレスとは、「コマンドの作用する範囲」という意味。

sedのデフォルト動作
すべての行を自動的に出力する仕様(-nオプションで抑制可能)
各行が最低1回は必ず出力される
-nオプションを付けない限り、全行が必ず1回出力される

sed コマンドの形式

sedによるテキスト編集
sed [オプション] <スクリプト> <対象ファイル>


※『新しいLinuxの教科書 第2版』より、画像引用

スクリプト:「アドレス」と「コマンド」を組み合わせた文字列
コマンドは、引数とフラグを取ることがある。
アドレスは省略することができ、その場合はすべての行が対象になる。

基本概念

sedには2つの重要な「作業領域」がある

https://deep.tacoskingdom.com/blog/131 より画像引用

① パターンスペース
現在処理中の行が格納される場所(デフォルトの作業領域)
sedがファイルを1行ずつ読み込むとき、その行が最初に入る場所
通常のsedコマンド(s/置換/ここ/など)はすべてパターンスペースに対して作用する
読み込んだ行ストリームごとに「パターンスペース」という入れ物のように使えるメモリ空間にコピーされ、行が一つ一つ読み込まれる度にパターンスペースの中のテキストの内容が更新されている。

https://deep.tacoskingdom.com/blog/131 より画像引用

② ホールドスペース
データを一時的に保持しておくための補助的なスペース
デフォルトでは空
明示的にコマンドを使わないとアクセスできない
複数行にまたがる処理をするときに便利

主要なコマンド

コマンド 意味
h パターンスペース→ホールドスペースにコピー(上書き)
H パターンスペース→ホールドスペースに追加(改行して追加)
g ホールドスペース→パターンスペースにコピー(上書き)
G ホールドスペース→パターンスペースに追加(改行して追加)
x パターンスペースとホールドスペースを交換

● d コマンド:行の削除

// 1行目を削除
sed 1d drink.txt

// 2行目から5行目までを削除
sed 2,5d drink.txt

// 3行目から最後まで削除
sed '3,$d' drink.txt

// 先頭がBで始まる行を削除(正規表現を使用)
sed /^B/d drink.txt

$を利用する際はシェルに解釈させないために、スクリプト部分はシングルクォートでくくる必要がある。

● p コマンド:行の表示

sed コマンドは行を読み込むと、まずパターンスペースという場所に一旦コピーし、そのパターンスペースに編集コマンドを実行してから、最後にパターンスペースの内容を出力する。

pコマンドの役割
指定した行を追加で出力(自動出力に上乗せする形)
→ 結果的に指定行だけ2回出力される

流れ

※『新しいLinuxの教科書 第2版』より画像引用

-n オプション:パターンスペースの出力をさせないようにする

パターンスペースに入れられた内容をその都度標準出力するpコマンドが暗黙的ルールで動作しているので、「何もしない」ことをsedにさせたい場合、このデフォルトでパターンスペースの内容を標準出力する機能を抑制する必要がある。

p コマンドを n オプションと同時に利用することで特定の行だけ表示させることができる。
-n オプションによりパターンスペースの出力をさせないという手法は、置換機能で「置換が発生した場合にだけ出力する」ケースなどに利用される。

● s コマンド:行の置換

sedによる文字列の置換の書式
s/置換元文字列/置換後文字列/フラグ

フラグは省略可能

g フラグ:見つかったすべての文字列を置換する

置換文字列には正規表現を利用できる

sed 's/B.*r/Whisky/g' drink.txt

・sコマンドを使用する際は、常にスクリプト全体をシングルクォートでくくっておくことが推奨される。
置換後文字列を指定せず空にすることで、空文字に変換(=置換前文字列を削除)することができる
・パターンスペースを出力しない -n オプションと、置換が発生した場合に出力する p フラグを組み合わせて利用することで、置換が発生した行だけを表示することができる。
※長いテキストを置換する場合に、どこで置換が発生しているかを確認するときに便利

sed での拡張正規表現

sed では正規表現は基本正規表現として解釈される。
拡張正規表現を使用したい場合は、-Eオプションをつける。
また、-Eオプションの代わりに-rオプションを付けても拡張正規表現が利用できる。
加えて、Linuxのsed(GNU sed)の独自拡張により、拡張正規表現である+? の直前に\バックスラッシュをつけることで、基本正規表現として利用することができる。

sed -E 's/Be+r/Whisky/' drink.txt
sed 's/Be\+r/Whisky/' drink.txt

※これから学習をしていく人には、他の環境と互換性のある-Eオプションを使うことが推奨される。

後方参照

正規表現を( )でグループ化した際に、そのマッチした文字列を\1のなどの数値で参照できる機能。
複数のグループ化をした場合には、それぞれ\1\2のように行の先頭からの順番に参照できる。
後方参照は\1, \2, \3のように使い、この数字はキャプチャグループの順番に対応している。

基本ルール
最初の( ) → \1 で参照
2番目の( ) → \2 で参照
3番目の( ) → \3 で参

正規表現の中で「前に出てきた同じパターンをもう一度使いたい」ときに便利な機能。

基本正規表現と拡張正規表現

基本正規表現(BRE) 拡張正規表現(ERE)
\( \)でグループ化し、\1で参照 ( )でグループ化し、\1で参照
sed 's/My (.*\)/--\1--/' drink.txt

アドレス指定

sコマンドで置換するときは、dコマンドやpコマンド同様アドレスを指定できる。

区切り文字の変更

sコマンドで置換するとき、文字列内で/(スラッシュ)という文字そのものを指定したい場合には、区切り文字と区別するために\(バックスラッシュ)を付けてエスケープして\/と記述する。

さらにスマートな方法として、区切り文字を変える方法がある。
sの後ろの文字は自動的に区切り文字とみなされるため、一般的によく !% がよく使われる。

mabomabo

awk コマンド:パターン検索・処理言語

テキストの検索や抽出・加工などの編集操作を行なうためのコマンド。
sed のようにシェルから指定した編集操作をテキストに対して実行し、その編集結果を表示する。

動作の流れ

https://wlab.page/blog/awkコマンド/ より画像引用

特徴

テキストのパターン処理に強い
特定のパターン(行や列)にマッチしたデータを抽出・加工できる。
(例)ログファイルから特定の条件に合致する行だけを抽出。

フィールド(列)単位の操作が簡単
デフォルトでスペースやタブで区切られた列を扱え、$1(1列目)、$2(2列目)のようにアクセス可能。
(例)CSVやログの特定列を集計。

スクリプト言語としての機能
変数、ループ、条件分岐などプログラミング言語のような構文を持ち、複雑な処理も記述可能。

awkコマンドの形式

書式
awk  <スクリプト> <対象ファイル>

// スクリプトの部分はシェルに解釈されないよう''で囲む
awk 'パターン { アクション }' ファイル

対象ファイルを指定しない場合、標準入力から読み込み、フィルタとして振る舞う。

スクリプトの書式
パターン { アクション }

パターン:アクションを実行するかどうかの条件を記述
この条件は対象テキストを1行読み込むごとに判定される。
※処理中に読み込んでいく1行の入力テキストをレコードと呼ぶ。
パターンは省略可能。その場合、すべてのレコードに対してアクションが実行される。

アクション:テキストの抽出や置換、削除などの実際のテキスト編集処理を記述
パターンにマッチした場合にのみ、このアクションが実行される。

printとフィールド変数

awkコマンドでもっとも使用される処理は、特定のフィールドを抽出して表示するという列選択

レコードとフィールド

https://wlab.page/blog/awkコマンド/ より画像引用

awkは各レコードを自動的にフィールドに分割し、それぞれのフィールドを$1などのフィールド変数に代入する。レコード全体は$0に代入される。
フィールド分割の際は、スペースもしくはタブが区切り文字とみなされる。
lsコマンドのように各フィールド間のスペース数がまちまちの表示を加工するのに便利

printする際、変数をカンマ付きで並べると、それぞれの値がスペース区切りで表示される。
※変数をスペースで並べると、表示結果にはスペースが入らないため注意。

組み込み変数 $NF
NF:「Number of Fields」の略で、現在のレコード(行)に含まれるフィールド(列)の数を表す、代入されている組み込み変数。
$NF:NF 変数の値を使って、その行の最後のフィールドの内容を参照するための特別な変数。$NFをprintするとレコードの最後のフィールドが表示される。

※awkではアクション内で演算が行えるため、$(NF-1)「後ろから数えて2番目のフィールド」のように表示することもできる。

パターンの指定


※『新しいLinuxの教科書 第2版』より画像引用

awkで正規表現のパターンを指定するには、/(スラッシュ)で囲って記述する。

awk コマンドで比較をする際に使用するチルダ ~ は、正規表現によるパターンマッチングを行なうための演算子。特定のパターンが含まれているかどうかを評価するために使われる。
なお、正規表現を書く際には比較対象を省略することができる。その場合、レコード全体が対象となる。

変数 ~ /正規表現/
左側の 変数 の値が、右側の /正規表現/ で指定されたパターンにマッチする場合に真(true)を返す。

変数 !~ /正規表現/
チルダの前に ! を置くと、否定の意味になる。
左側の 変数 の値が、右側の /正規表現/ で指定されたパターンにマッチしない場合に真(true)を返す。

アクションの省略

アクションを省略するとレコードを表示する。
{print $0}が実行される

printアクションは引数に何も指定しないとレコードを表示する
{print $0}が実行される

よって、以下はすべて同じ意味になる。

awk '$9 ~ /^cp/'
awk '$9 ~ /^cp/ {print}'
awk '$9 ~ /^cp/ {print $0}'

-F オプション "Field Separator"
awkコマンドで入力フィールドの区切り文字(フィールドセパレータ)を指定するために使用する。
awkは、デフォルトでは空白やタブをフィールドの区切り文字としているが、-Fオプションを使用することで、カンマ(,)やコロン(:)など、任意の文字を区切り文字として指定できる。

書式
awk -F'区切り文字' '{ アクション }' ファイル名

ENDパターン
awkコマンドにおけるENDパターンは、入力ファイルのすべての行を読み終えた後、つまりawkの処理が終了する直前に実行される特別なパターン。
ENDは、すべての入力行の処理が完了した後に実行されることを示すキーワード。
ENDパターンに続くアクションは、ファイルの最終処理や結果の出力などに使用される。

ENDパターンの構文
END { アクション }

{ アクション }: ENDパターンにマッチしたとき(つまり、ファイルの読み込みが完了したとき)に実行するawkのコマンドを記述する。

NR
"Number of Records"の略で、awkが入力ファイルまたは標準入力から読み込んだレコード(行)の総数を表す組み込み変数。

NRの動作
・awkは、入力ファイルを1行ずつ読み込みながら処理を行なう
・NRは、行を読み込むごとに1ずつ増加する
・NRの値は、現在の行番号を表す
・BEGINパターン内では、まだ行が読み込まれていないため、NRは0
・ENDパターン内では、すべての行が読み込まれているため、NRはファイルの総行数を表す

一度作成したawkスクリプトは .awk ファイルに保存することで、スクリプトファイルを -f オプションで読み込んで実行することができる

mabomabo

シェルスクリプト


※『新しいLinuxの教科書 第2版』より画像引用

シェルのコマンドラインをあらかじめ記述しておくファイルのこと。
実行したい一連のコマンドをあらかじめファイルに記述しておき、そのファイルをシェルに読み込ませることでコマンドを実行することができる。
複雑なコマンドであっても毎回手で入力する必要がなくなる。

シェルスクリプトの作成

基本構文
// シェバンの記述
#!/bin/bash

// コメントの記述
# これはコメントです

シェルスクリプトの慣習として、ファイル名の拡張子を.shにする

シェバンの記述

※『新しいLinuxの教科書 第2版』より画像引用

スクリプトの1行目に、どのシェルで実行するかを記述する。一般的には、#!/bin/bash と記述する。
シェルから命令を受けたLinuxカーネルは、まず対象ファイルの先頭を確認し、#!があった場合、その後ろに書かれたコマンドを実行するという動作をする。

シェバンに書かれたシェルスクリプトは、実質的にはLinuxカーネルに展開されて、シェルに自分自身のファイル名を引数として与えて実行することになる。

コメントの記述
# から始まる行はコメントとして扱われ、実行時には無視される。スクリプトの説明やメモを記述するのに使う。

コマンドの記述
実行したいコマンドを記述する。複数のコマンドを記述する場合は、改行で区切る。

chmod コマンドでファイルに実行権限を追加する
シェルスクリプトは実行されるファイルであるため

sourceコマンド:ファイルからコマンドを読み込んで実行する


※『新しいLinuxの教科書 第2版』より画像引用

指定したファイルの内容をそのままコマンドラインに入力したときと同じように実行する。
シェルスクリプトに書かれた1行1行を、今カーソルがあるその場に「流し込む」というイメージ。
→ 指定されたファイルの内容を現在のシェル環境に「取り込む」ようなイメージ。

sourceコマンドは対象ファイルを直接実行するわけではないため、ファイルに実行権限は不要
bashではsourceコマンドと同じ意味を持つ .(ドット)コマンドがある。

sourceコマンドは、指定されたファイルの内容を現在のシェルプロセス(親プロセス)内で直接実行し、ファイル内で設定された変数や関数など、ファイルの内容を現在のシェルに読み込んで実行するという動作になる。

・sourceコマンドは、シェルスクリプトを現在のシェル環境に読み込んで実行するために使用される。これにより、スクリプト内で定義された変数、関数、エイリアスなどが、現在のシェル環境に反映される。
他のシェルスクリプトで定義された関数などを現在のシェルで利用したい場合にも使用される。
・sourceコマンドは、新しいシェルプロセスを開始せずに、現在のシェル環境でスクリプトを実行する。
・スクリプト内で設定された内容は、現在のシェル環境に直接影響を与える。
・sourceコマンドは、スクリプトの実行結果を現在のシェル環境に反映させたい場合に便利
※sourceコマンドは、外部ファイル(シェルスクリプトなど)の内容を現在のシェル環境に取り込むためのコマンドであり、環境変数として明示的に設定しない限り、子プロセスには引き継がれない。

※sourceコマンドは、実行後はカレントシェルでシェルスクリプトを実行するため、実行後は元のシェルに影響を及ぼす

通常のファイル実行との違い
通常のファイル実行では、新しい子プロセスが生成され、その子プロセス内でスクリプトが実行される。
子プロセス内で設定された変数や関数は、親プロセスである現在のシェル環境には影響を与えないため、通常のファイル実行は、現在のシェル環境とは独立した新しい環境でスクリプトを実行する。
ファイルそのものを独立したプロセスとして実行する。

通常のスクリプト実行では、新しい子プロセスが生成され、その子プロセス内でスクリプトが実行される。
子プロセス内で設定された変数や関数は、親プロセスである現在のシェル環境には影響を与えない。

「スクリプト実行」と「ファイル実行」の違い
スクリプトの実行
スクリプト:特定のプログラム(シェル、Python、Perlなど)によって解釈され、実行されるテキストファイル。
・スクリプトファイルには、プログラムが実行する命令が記述されている。
・スクリプトの実行は、インタプリタと呼ばれるプログラムによって行われる。
・インタプリタは、スクリプトファイルを読み込み、記述された命令を1行ずつ解釈して実行する。
・スクリプトの例:シェルスクリプト(.sh)、Pythonスクリプト(.py)、Perlスクリプト(.pl)

ファイルの実行
ファイルの実行は、実行可能ファイル(バイナリファイル)を直接実行することを指す。
・実行可能ファイルには、コンピュータが直接実行できる機械語の命令が記述されている。
・ファイルの実行は、OSのローダーと呼ばれるプログラムによって行われる。
・ローダーは、実行可能ファイルをメモリにロードし、実行を開始する。
・ファイルの例:プログラム(.exe、.bin)、共有ライブラリ(.so、.dll)

sourceコマンドの主な目的

環境変数の設定
シェルスクリプト内で設定された環境変数を、現在のシェル環境に反映させることができる。
これにより、他のコマンドやスクリプトから、設定された環境変数を参照できるようになる。

関数の定義
シェルスクリプト内で定義された関数を、現在のシェル環境で使用できるようになる。
これにより、複数のスクリプトで共通の関数を再利用できる。

エイリアスの設定
シェルスクリプト内で設定されたエイリアスを、現在のシェル環境で使用できるようになる。
これにより、よく使うコマンドのエイリアスをまとめて設定できる。

設定ファイルの読み込み
.bashrcや.profileなどの設定ファイルを読み込み、シェル環境をカスタマイズできる。

※シェルスクリプト内で設定された変数は、通常、そのスクリプトが実行されるシェルプロセス内でのみ有効。しかし、環境変数として設定することで、その変数をシェル内部や他のプロセスからも参照できるようになる。

シェル変数と環境変数
シェル変数
・シェルスクリプト内で定義された変数。
・スクリプトが実行されるシェルプロセス内でのみ有効。
・子プロセスには引き継がれるが、親プロセスや他のシェルからは参照できない。

環境変数
・システム全体で有効な変数。
・親プロセス、子プロセス、他のシェル、他のプログラムからも参照できる。
・exportコマンドを使用して設定する。

exportコマンドの役割
exportコマンドは、シェル変数を環境変数として設定するために使用する。
export 変数名 の形式で実行すると、指定されたシェル変数が環境変数となり、子プロセスに引き継がれる。
export 変数名=値 の形式で実行すると、環境変数の設定と同時に、値の代入も行える。

シェルに引数としてファイルパスを指定した場合

シェルに引数としてファイルパスを指定すると、指定されたファイルの種類と、どのように指定されたかによって、プログラムが実行されたり、スクリプトが実行されたり、ファイルが開かれたりする。

① 実行可能ファイル(バイナリファイル)の場合
指定されたファイルパスが実行可能ファイル(コンパイルされたプログラムなど)を指している場合、
シェルは新しい子プロセスを生成し、その子プロセス内で指定されたプログラムを実行する。

(例)./my_progra
この場合、シェルはmy_programというプログラムを子プロセスで実行する。
プログラムは、ファイルパスで指定された場所からメモリにロードされ、実行される。
プログラムは、標準入力、標準出力、標準エラー出力を通じて、シェルと通信できる。

② シェルスクリプトの場合
指定されたファイルパスがシェルスクリプト(.shファイルなど)を指している場合、シェルはスクリプトの内容を読み込み、解釈して実行する。

(例)bash my_script.sh
この場合、シェルはmy_script.shの内容をBashシェルで実行する。
スクリプト内で記述されたコマンドは、シェルによって順番に実行される。
スクリプトは、引数を受け取ったり、環境変数を参照したりできる。

③ その他のファイルの場合
指定されたファイルパスが、シェルが直接実行できない種類のファイル(テキストファイル、画像ファイルなど)を指している場合、シェルはエラーメッセージを表示するか、デフォルトのプログラムでファイルを開こうとします。

(例)less my_text.txt
この場合、シェルはlessコマンドを起動し、my_text.txtの内容を表示する。
ファイルの処理方法は、ファイルの種類と、シェルがどのように設定されているかによって異なる。

ファイルパスの指定方法
・絶対パス: ファイルシステムのルートディレクトリからの完全なパスを指定する。
(例)/home/user/my_file.txt
・相対パス: 現在の作業ディレクトリからの相対的なパスを指定する。
(例)./my_file.txt(現在のディレクトリにある場合)

シェルスクリプトの実行方法

シェルスクリプトは実行する方法によって動作が変わるため、どの方法でシェルスクリプトを実行するか意識しておく必要がある。

① ファイル名のみを指定して実行する(./スクリプト名.sh
スクリプトファイルに実行権限が付与されている必要がある。
スクリプトの1行目に記述されたシェバン(#!/bin/bash など)に従って、適切なシェルが起動され、スクリプトが実行される。
この場合、新しいプロセス(サブシェル)で実行されるため、現在のシェル環境には影響を与えない。

② シェルの引数として実行する(bash スクリプト名.sh
明示的に新しい bash プロセス(サブシェル)を起動し、その中でスクリプトを実行する。
スクリプト内で設定された変数や関数は、現在のシェル環境には影響を与えません。

③ sourceコマンドを利用して実行する(source スクリプト名.sh または . スクリプト名.sh
スクリプトの内容が現在のシェル環境に読み込まれ、実行される。
スクリプト内で設定された変数や関数は、現在のシェル環境に直接影響を与える。
この場合、新しいプロセスは生成されない。現在のシェルプロセスで実行される。

サブシェル:現在のシェルから新しく起動されるプロセスのシェル
※元のシェルとは別物。環境変数は引き継がれるが、エイリアスなどの設定は引き継がれない。
サブシェルは、現在のシェル(親シェル)から派生した子プロセス
・親シェルのコピー: サブシェルは、親シェルの環境(変数、関数、エイリアスなど)をコピーして作成される。
・独立したプロセス: サブシェルは、親シェルとは独立したプロセスID(PID)を持ち、別のメモリ空間で動作する。
・環境の分離: サブシェル内で行われた変更(変数の設定や変更、カレントディレクトリの移動など)は、親シェルには影響を与えない。環境を隔離するために重要な特性。
・一時的な環境: サブシェルが終了すると、そのサブシェル内で行われた変更はすべて失われる。


※『新しいLinuxの教科書 第2版』より画像引用

sourceコマンドの利用例

一般的に、多くのシェルスクリプトはsourceコマンドではなく、.test.shのようにファイル名を指定した形式で実行される

その理由は、
・シェバンによりシェルを指定することで、ユーザが使っているシェルが何であっても正常に動作させることができる
・sourceコマンドによる実行で現在のシェルの状態を引き継ぐと、設定の違いによってシェルスクリプト作成時には想定していない動作をすることがある。また、終了後も元のシェルに影響を及ぼしてしまう
といったものが挙げられる。

sourceコマンドでは、設定を引き継ぐという特徴を利用した使い方をする。
bashの設定ファイル ~/.bashrc は、.profile(Ubuntu)からsourceコマンドで読み込まれる。
~/.bashrcファイル自体もシェルスクリプト

その他、複数のシェルスクリプトが同一の値を参照したい場合などに、設定ファイルをシェルスクリプトとして書いておいて、それをsourceコマンドで読み込む、という使い方がされる。

シェルスクリプトを配置する

サーチパス:シェルからコマンドを実行する際に、コマンドの実体ファイルを探すディレクトリ。環境変数PATHに設定されており、echo コマンドでその値を確認することができる。
また、通常サーチパスにカレントディレクトリは登録されていないため、シェルスクリプトのファイル名を指定するだけでは実行できない。
サーチパスにないファイルを実行するには、相対パスもしくは絶対パスでファイルを指定する必要がある。

独自のコマンドをつくる
catやlsのようにファイル名で実行できるようにするために、ホームディレクトリの下のbinというディレクトリがよく使用される。これをサーチパスに追加することで、コマンドのように実行できるようになる。
一例として、~/binというディレクトリを作成し、サーチパスに追加する(Ubuntu ~/.profileに$HOME:binを追加)。

シェルのファイル実行の流れ
ファイル名に「/」(スラッシュ)が含まれているかどうかでまず選別される。
・スラッシュがある場合:指定されたパスを直接参照し、PATH変数は参照しない
・スラッシュがない場合:コマンド名と解釈され、PATH変数を順番に検索し、実行される

sourceコマンドとパス

sourceコマンドは指定されたファイルを実行するが、このときパスを指定せずファイル名だけを与えると、bashはサーチパスの中からファイルを探す。
ただし、この機能は予期せぬファイルをsourceコマンドで読み込んでしまう危険性があるため、基本的には、sourceコマンドを使うときにはファイルを絶対パスまたは相対パスで記述してファイル名だけを記述するのを避けた方が無難。

sourceコマンドでファイルをサーチパスから探さないようにする方法
shopt -u sourcepath
mabomabo

シェルスクリプトの基本

シェルスクリプトの行

シェルスクリプトでは、実行したいコマンドラインをファイルに記述することでコマンドが実行される。
複数のコマンドを実行させたい場合、順番に何行でもコマンドを書くことができる。
複数のコマンドを ;(セミコロン)で区切ることで、1行にまとめて書くことができる。

#!/bin/bash

echo "root"; cd /; ls-l

コマンドラインが長くなってしまう場合には、行末に\(バックスラッシュ)を置くことで途中で改行できる

#!/bin/bash

echo \
               "root"

シェルを利用する際に \ (バックスラッシュ)を利用することができ、文末に入力してEnterキーを押すと、プロンプトが > に変わる。

$ echo \
>

セカンダリプロンプト:「まだコマンドラインが終了していないため、入力してください」という意味
この文字はシェル変数PS2でカスタマイズすることができる。
セカンダリプロンプトからも、\でさらに改行を続けていくことができる。最後にコマンドを実行したいところで、\をつけずにEnterキーを押せば全体のコマンドラインが実行される。

|を利用してパイプラインでコマンドをつなぐ際にも、|の直後に改行を入れて記述することもできる。
長いパイプラインを途中で改行して見やすくしたいときに便利。

コメントアウト

#:シェルスクリプトでは#を書くとその行の終わりまでがコメントとなる。
行の先頭に書くことで行全体をコメント行とすることも、コマンドの後ろに#を置いて行の途中にコメントを書くこともできる。

変数

シェル変数:シェルスクリプトで通常のプログラミング言語と同じように値を格納する変数
シェル変数に値を代入するには、「<変数名>=<値>」という形式で指定する。
変数の値を参照するには、変数の前に$を付ける

変数の書き方の注意点

① 代入時には$を付けない
変数の前に$を付けるのは、値を参照したいときだけ
「変数名に$をつけることで値を取得する」

=の前後にはスペースを入れない

③ 変数名に利用できる文字
変数名に利用できる文字は、アルファベットと数値、_(アンダースコア)だけ
数値は先頭の1文字目に使うことができない
変数名の先頭は必ずアルファベットかアンダースコアにすること。
※変数名は大文字・小文字どちらでも問題ない。一般的に、環境変数には大文字、それ以外の通常のシェル変数は小文字が使用されることが多い。

④ 変数名の区切りを明示する
変数名の部分を{ }で囲むと変数名の区切りを明示することができる。
例えば、変数展開した値に文字列を連結したい場合、{ }で囲まないと文字列全体が変数名の一部とみなされてしまうことがある。

クォーティング

スペースを含むファイル名をコマンドの引数として指定する場合、コマンドの引数を'(シングルクォート) または "(ダブルクォート)で囲む。
こうすることで、' または "内の文字列が、スペースも含めて1つの単語とみなされるようになる。
また、クォーティングすると、シェルによるスペースやメタ文字の解釈をさせず、まとめて1つの文字列として扱うことができる。

クォート中の変数展開

'(シングルクォート)
シングルクォートの中で、$も特殊な意味を失うため変数は展開されず、$はそのまま$記号(文字として認識される)となる。

"(ダブルクォート)
ダブルクォートの中では$による変数展開や、コマンド置換は有効のまま。
変数を使って文字列を組み立てたい場合に使用する。
※ダブルクォートの中で$の前に\を置いてエスケープすると、$記号そのものを出力することができる。

コマンド置換

コマンドの出力結果をシェルスクリプト中で利用する方法
コマンド置換を利用することでコマンドの結果を文字列として取得することができる。

コマンド置換は$( )という形式で括弧内に実行したいコマンドを記述する。
シェルスクリプト実行時に$( )の部分がコマンドの標準出力で置き換えられる。
コマンド置換は"(ダブルクォート)の中でも有効

位置パラメータ


※『新しいLinuxの教科書 第2版』より画像引用

$1, $2, $3 ... と1から順に並んだ変数のこと。
$0にはシェルスクリプトを実行したときのシェルスクリプト名が格納される。位置パラメータに似ている特殊パラメータの1つ。
シェルスクリプトからコマンドライン引数を扱うには、位置パラメータと呼ばれるシェル変数を使用する。
シェルスクリプト中で引数を使って処理を組み立てるには、位置パラメータを使用すればいい。

引数の個数

コマンドラインに指定された引数の個数は、特殊パラメータ$#という変数で参照できる。
引数の指定が必須なスクリプトを作るときに、引数の個数のチェックをする際に利用できる。

引数全体の参照

位置パラメータはコマンドライン引数を自動的に分割するが、引数を分割せずまとめて扱うには、$@ または $* を利用する。
$@$*の違いは"(ダブルクォート)で括ったときに現れる
"$@"は位置パラメータがそれぞれ1つずつの文字列として展開される。
"$*"は引数全体が1つの文字列として展開される。

ラッパー wrapper
既存のコマンド、スクリプト、またはプログラムを包み込むように作成された別のスクリプトのこと。
ラッパーは、元の対象に対して何らかの追加機能、変更、または抽象化を提供することを目的としている。

コマンドライン引数関連のシェル変数 まとめ

変数 内容
$0 実行時のシェルスクリプト名
$1, $2 ... コマンドライン引数の値(位置パラメータ)
$# 位置パラメータの個数
$@ すべての位置パラメータ
ダブルクォートで囲むと、それぞれの位置パラメータがダブルクォートで囲まれる
$* すべての位置パラメータ
ダブルクォートで囲むと、全体が1つの文字列としてダブルクォートで囲まれる
$? 終了ステータスの取得
mabomabo

制御構造

値による条件分岐や繰り返し処理を行なう構造

if 文

if は条件を評価して、その真偽に応じて処理を分岐するための機能をもつ。
シェルスクリプトにおけるインデント(字下げ)はタブでもスペースでもOK。省略してもエラーにはならない。

記述上の注意点

条件を書いた後の;(セミコロン)を省略することができない
セミコロンを抜きたい場合は改行して then を記述する。

if の後ろにはコマンドを置く

[ "$1" = "bin" ][はコマンドであり、bashの組み込みコマンドである。
[はコマンドで、その後ろに条件式という形で引数を取り、最後に] という引数を取る。
この引数を並べるために[の後ろはスペースで区切る必要がある。


※『新しいLinuxの教科書 第2版』より画像引用

if と終了ステータス

[コマンドは引数に書かれた条件式を判定し、その条件が正しければ0を、そうでなければ0以外を終了ステータスとして返すコマンド
if 文では真偽の判定を行なう際、まず後ろに指定されているコマンドを実行する。そして、その終了ステータスが0であった場合は真、そうでない場合は偽と判定する。
そのため、if文の後ろには[以外の任意のコマンドを書くことができる。

※いくつかのコマンドには、コマンドの終了ステータスだけを利用したい場合のために、quietモード -q(静かなモード)が用意されている。

終了ステータス
0 (ゼロ): コマンドが正常に完了したことを示す。
0以外の数値: コマンドが何らかのエラーで失敗したことを示す。エラーの種類や原因に応じて異なる数値が返されるが、具体的な値はコマンドによって異なる。

終了ステータスの確認方法:直前に実行されたコマンドの終了ステータスは、特殊変数 $? に格納されている
コマンドの終了ステータスを $? から取得することで、そのコマンドの終了状態を知ることができる。

主な終了ステータス
・1: 一般的なエラー
・2: シェル組み込みコマンドの誤用
・126: コマンドの実行権限がない
・127: コマンドが見つからない
・128 + シグナル番号: コマンドがシグナルによって終了した場合(例: SIGINT (Ctrl+C) なら 130)
・255: 範囲外の終了ステータス

test コマンドと演算子

test コマンドと [はほぼ同じ機能を持ち、2つのコマンドの違いは最後に引数]をとるかとらないかという点を除いて同じ動きをする

同じ内容
if [ "$1" = "bin" ]; then
if test "$1" = "bin"; then

文字列の比較


※『新しいLinuxの教科書 第2版』より画像引用

-zは対象が空文字列であれば真となる。
→ 変数に値がセットされているかどうかの判定に利用される
→ 値の指定を省略した場合には、デフォルト値を設定する、というシェルスクリプトを作成することができる

整数の比較


※『新しいLinuxの教科書 第2版』より画像引用

これらの演算子は整数しか扱うことができないことに注意

ファイル属性の評価


※『新しいLinuxの教科書 第2版』より画像引用
※詳しくはbashのマニュアル「条件式(CONDITIONAL EXPRESSIONS)」またはhelp test参照

演算子の結合


※『新しいLinuxの教科書 第2版』より画像引用

結合演算子を使用した例

※『新しいLinuxの教科書 第2版』より画像引用

( )で囲むと条件式をグループ化できる。
-o(OR)は-a(AND)よりも優先度が低いため、-a, -o, ! を組み合わせて使うとき、優先順位を指定するために使用する。

条件式のグループ化

※『新しいLinuxの教科書 第2版』より画像引用

()はメタ文字であるため、実際に利用するためには\(バックスラッシュ)によってエスケープして利用する。

&&||

コマンドの終了ステータスに関連したbashの構文として、複数のコマンドを連結して順に評価する記法
2つのコマンドを連結して、コマンド1 && コマンド2またはコマンド1 || コマンド2という形式で利用する。

&&: コマンド1 && コマンド2
コマンド1の終了ステータスが0(ゼロ)であるとき、コマンド2を実行する。
※条件分岐はif文を利用して記述できるが、&&で連結すると1行でシンプルに書くことができる。

||: コマンド1 || コマンド2
コマンド1の終了ステータスが0(ゼロ)以外であるとき、コマンド2を実行する。
つまり、コマンド1が正常終了しなかったときだけコマンド2を実行する。

if文での&&の利用

if文で&&を利用すると、「複数のコマンドの終了ステータスすべてがゼロ」というAND条件を記述することができる

...
if [ "$int1" -gt 3 ] && [ "$int1" -lt 6 ]; then
...

if文では testコマンド以外のコマンドも自由に書くことができるため、grep コマンドを複数書いてすべてにマッチしたとき、などの書き方もできる。

if文で||を利用すると、どれか1つのコマンドの終了ステータスがゼロであったとき、という OR条件になる。

※AND条件やOR条件は-a-oを使っても表現できるが、[コマンドの中だと可読性が悪く、優先順位がわかりにくくなるため、コマンド内での-a-oは推奨されていない。

シェルスクリプトの終了ステータス

特に明示がなければ、シェルスクリプトの中で最後に実行したコマンドの終了ステータスがシェルスクリプトの終了ステータスになる。

※『新しいLinuxの教科書 第2版』より画像引用

明示的に終了ステータスを指定したい場合は、exitコマンドを使用する。

書式
// 指定した終了ステータスを返す
exit <終了ステータス>

exit コマンドを実行するとそこでシェルスクリプトは終了して指定の終了ステータスを返す。
エラー時にゼロ以外の終了ステータスを返すことで、シェルスクリプトが別のプログラムから呼ばれた際にエラー処理を行なわせることができるようになる。

なお、exitコマンドで終了ステータスの指定を省略すると、シェルスクリプトの終了ステータスは最後に実行したコマンドの終了ステータスとなる。

mabomabo

制御構造

値による条件分岐や繰り返し処理を行なう構造

for文

スペースやタブで区切られた単語のリストに対して繰り返し処理を行なう構文。

for文の構造(書式)
for 変数名 in リスト
do
    繰り返す処理
done

繰り返し処理の中では、リストから取り出した要素の値が変数名で参照できる。
リストの部分には、固定文字列だけでなく、パス名展開やコマンド置換も利用できる。(ex. *.html)

seqコマンド
指定した範囲の数値を生成し、標準出力に出力するコマンドラインユーティリティ。
連続した数列を簡単に生成できるため、スクリプト処理などで繰り返し処理を行なう際に役立つ。

数値列を出力する(書式)
seq <開始値> <終了値>

コマンドライン引き数とfor

for文ではリストとして$@を指定して、すべてのコマンドライン引数に対して処理を行なうケースが多いため、in <リスト>を省略すると自動的に$@がリストの対象とみなされるようになっている。
よって、以下の2つは同じ意味
for parameter in "$@"(初めのうちは推奨)
for parameter

mabomabo

制御構造

値による条件分岐や繰り返し処理を行なう構造

case文

指定された文字列がパターンにマッチするかどうかを判断し、マッチしたパターンに対応する処理を行なうための制御構造
文字列によって処理を分岐する場合、if文で1つ1つ比較するよりも便利。

case文の構造・書式
case <文字列> in 
        <パターン1>)
            `処理1`
        ;;
        <パターン2>)
            `処理2`
        ;;
...
esac

esaccaseの逆表示

case で指定された文字列は、各パターンにマッチするかどうか上から順に評価され、マッチしたパターンのブロックに書かれた処理を実行する。
どのパターンにもマッチしなければ、何も実行せずにcase文を抜ける。

caseではパターン部分に文字列だけでなく、パス名展開と同様のワイルドカードを利用できる。
* は任意の文字列を、 ?は任意の1文字を表す。
*だけを指定すると、空文字列を含めてどんな文字列にもマッチする。そのため、*1文字は最後のパターンとして、どのパターンにもマッチしなかった場合の処理を書くために利用される。

その他、| を利用して、複数のパターンを記述することもできる。その場合、そのうちどれかのパターンにマッチすればブロックの処理が実行される。

mabomabo

制御構造

値による条件分岐や繰り返し処理を行なう構造

while 文

指定した条件が真である限り、繰り返し処理を行なう制御構文

while文の構造(書式)
while <コマンド>
do
    "繰り返し処理"
done

whileの後ろにはコマンドが置かれる。多くの場合、if文と同様にtestコマンドによる条件式が書かれる。
これは if文 と同様に、コマンドの終了ステータスがゼロであれば真とみなされ、doからdoneのブロック内に書かれた処理が繰り返し実行される。

算術式展開(Arithmetic Expansion)

基本構文
$(( 算術式 ))

この構文の中で記述された算術式は評価され、その結果が文字列として展開される。
$(( ))と2重のカッコでくくることによって、中に書いた文字列を計算式として扱うことができる。
シェル変数には$をつける必要はない。

sh で書かれたシェルスクリプトは、簡単な足し算をするだけでもexprという外部コマンドを利用しなければならない。
ループ処理内で expr コマンドを毎回呼び出すメカニズムは、シェルスクリプトが一行ずつ解釈・実行されるという特性に基づいている。

基本的な流れ(expr)

① シェルの解釈
シェル(通常は Bash)は、スクリプトファイルを上から一行ずつ読み込み、解釈する。
② ループの開始
for や while などのループ構造に遭遇すると、そのループの制御条件を評価する。
③ ループ本体の実行
制御条件が満たされている場合、ループの do から done (または相当する終端キーワード)までのコマンド群を順番に実行する。
④ expr コマンドの呼び出し
ループ本体の中で expr コマンドが記述されている行に到達すると、シェルは新しいプロセスをフォーク(複製)し、その子プロセス内で expr コマンドを実行する。
⑤ expr の処理
子プロセスとして起動された expr コマンドは、与えられた引数(算術式や文字列操作など)を解析し、計算結果や評価結果を標準出力に出力する。
⑥ 結果の取得
シェルは、子プロセスである expr コマンドの標準出力を読み取る。
⑦ 変数の代入など
expr の出力結果を変数に代入したり、他のコマンドの引数として利用したりする。
⑧ ループの繰り返し
ループの終端に達すると、再びループの制御条件が評価され、条件が満たされていれば④以降が繰り返される。条件が満たされなくなれば、ループを終了し、スクリプトの次の行に進む。

毎回呼び出される理由
expr はシェルに組み込まれた機能ではなく、独立した外部コマンド
そのため、シェルが算術演算や文字列操作を行なう必要があるたびに、新しいプロセスを生成して expr コマンドを実行する必要がある。

パフォーマンスへの影響
ループ内で expr を毎回呼び出すのは、プロセスの生成と終了にはオーバーヘッドがかかるため、ループの繰り返し回数が多くなると、スクリプトの実行速度が著しく低下する可能性があり非効率。

一般的に、シェル(Bash など)が外部コマンドを実行する際には、新しいプロセスを生成(フォーク)して行われる

mabomabo

シェル関数

シェルスクリプト内で定義できる、小さなプログラムのかたまりで、シェルスクリプトで使用される関数のこと。よく使う処理をまとめて再利用できる。処理をひとまとめにして、関数にしておくと便利。
本格的なシェルスクリプトを作成するときは、機能ごとに関数にまとめておくと見通しがよくなる。
シェル関数を利用する際は、利用する箇所よりも前に関数を定義すること

functionによる関数定義
function <関数名> ( )
{
        // 処理 //
}
カッコを省略した関数定義
function <関数名>
{
        // 処理 //
}
functionを省略した関数定義(この形式が最もよく使われている)
<関数名> ( ) 
{
        // 処理 //
}

シェル関数の中でも、位置パラメータ$1, $2... が利用できます。
ただし、シェル関数の中ではコマンドライン引数ではなく、関数への引数が参照される(*)

(*)解説
コマンドライン引数

ex1
./myscript.sh arg1 arg2

この場合、以下のようにスクリプトに渡した引数を$1, $2で受け取る。
$1arg1
$2arg2

関数に渡した引数
関数にも「関数に渡した引数」があり、関数の中では $1, $2 はスクリプトに渡された引数じゃなくて、関数に渡された引数を指す

ex2
#!/bin/bash

echo "Script arguments: $1, $2"

myfunc() {
  echo "Function arguments: $1, $2"
}

myfunc apple banana
ex2を実行
./myscript.sh one two
出力結果
Script arguments: one, two
Function arguments: apple, banana

・スクリプトに渡した引数 (one, two) → スクリプト内の $1, $2
・関数に渡した引数 (apple, banana) → 関数内の $1, $2
→ 関数に入ると $1, $2 の意味が「関数への引数」に切り替わるということ

$1, $2 が指すものは
・スクリプトの外: スクリプトに渡されたコマンドライン引数
・関数の中: 関数に渡された引数

シェル関数内では、位置パラメータが関数の引数へと置き換えられる
$0(特殊パラメータ)だけは関数名に置き換えられず、元のスクリプト名のままになっている。
通常、位置パラメータ $1, $2, ... は「コマンドライン引数」を指すが、関数を呼び出すとき、関数に引数を渡すと、関数の中では $1, $2 が関数に渡された引数に置き換わるということ。

シェル関数も終了ステータスを返す
シェル関数内で最後に実行されたコマンドの終了ステータスが、そのままシェル関数の終了ステータスになる。
明示的に終了ステータスを返すときは、シェルの組み込み関数である return コマンドを使用する。
return コマンドを実行すると、そこでシェル関数の動作は終了して呼び出し元に返る。

シェル関数を終了させる(書式)
return <終了ステータス>

コマンドにハイフンで始まる引数を指定する

Linuxのコマンドでは、基本的に-(ハイフン)で始まる引数はオプションとみなされる。

ハイフンで始まる引数をオプションではなく、例えば「--help」という名前のファイルを通常の引数として指定したい場合、ファイルを相対パスで指定することによって、先頭がハイフンではないためオプションと解釈させないようにできる。
別の方法として、コマンドと引数の間をハイフン2つで区切る方法もある。

コマンドライン中の-- には、それ以降はオプションではなく、通常の引数とみなす、という意味がある。これで一旦オプションを打ち切ってしまえば、それ以降はハイフンで始まる引数が指定できる。

上記はトラブルの原因になるため、名前がハイフンで始まるファイルはそもそも作らないことが推奨される


mabomabo

シェルスクリプトの活用

シェルスクリプトの欠点

シェルスクリプトを使うべきではないケース
① 大規模システムのプログラミング
シェルスクリプトでは独自のデータ型を定義できないことやコードをモジュールに分割する機能が不十分であることから、プロジェクトの規模が大きくなるにつれてプログラムの見通しが悪くなってしまう傾向にある。
また、有用な処理をパッケージとして管理、公開する環境が整っていないので、コードの再利用ができず必要な処理をアプリケーションごとに毎回書く必要がある。

② 高速性が必要な処理
シェルスクリプトは1行ずつコマンドを実行していく形式を取ることから、子プロセスを生成する処理(fork)が大量に発生する。そのため、他のスクリプト言語に比べて動作が遅くなる傾向にある。速度面を気にする場合はRubyのようなスクリプト言語の利用を検討する。

mabomabo

グローバル変数・ローカル変数


https://www.stechies.com/global-local-variables-python/ より画像引用

global キーワード

シェルスクリプト全体で有効な変数のこと
通常、シェルスクリプトで1度宣言した変数は、関数内の中などどこからでも参照や代入ができる。
これは、不用意に変数の値を書き換えると、関数の外にまで影響を及ぼしてしまう。
例えば、関数の中で変数の値を変更すると、呼び出し元でも値が変わってしまう。
プログラムを書く際、極力グローバル変数の利用を避けることが望ましい。

local キーワード

有効範囲をシェル関数の中だけに制限した変数のこと
変数の前にlocalをつけて宣言する。
関数の中で使う変数は、基本的にローカル変数として宣言して、影響範囲をなるべく狭くするようにすること

再帰


https://jennaro.hashnode.dev/the-recursive-algorithm-in-python より画像引用


https://www.geeksforgeeks.org/recursive-functions/ より画像引用

シェル関数の中から自分自身を呼び出して、入れ子のように処理を行なう方法。再帰呼び出しという。

再帰的な関数は、通常、以下の2つの重要な部分から構成される
ベースケース (Base Case)
再帰呼び出しが停止する条件。これがなければ、関数は永遠に自分自身を呼び出し続け、プログラムがスタックオーバーフローというエラーで停止してしまう。
ベースケースは、「これ以上は再帰する必要がない」という明確な停止条件を定義する。

再帰ステップ (Recursive Step)
関数が自分自身を、より小さな問題や簡単な入力で呼び出す部分。
再帰ステップでは、問題をより小さな部分に分割し、その小さな部分に対する結果を利用して、元の問題の解を導き出そうとする。

再帰を使うべき場面
・木の探索 (例: ファイルシステムのディレクトリ構造、XML/JSONの構造など)
・グラフの探索 (深さ優先探索など)
・分割統治アルゴリズム (例: マージソート、クイックソートなど)
・問題の定義自体が再帰的な場合 (例: 階乗、フィボナッチ数列など)

mabomabo

絶対パス表記からファイル名を取り出す

"/home/user/script/diary.sh"から"diary.sh"だけを取り出す方法として、シェルのパス名展開を利用した方法がある。

bashのパラメータ展開

記法 意味
${変数名#パターン} 最短マッチで、パターンに前方一致した部分を取り除く
${変数名##パターン} 最長マッチで、パターンに前方一致した部分を取り除く
${変数名%パターン} 最短マッチで、パターンに後方一致した部分を取り除く
${変数名%%パターン} 最長マッチで、パターンに後方一致した部分を取り除く

最長マッチ:指定したパターンにマッチする文字列のうち、もっとも長いものを指す
最短マッチ:指定したパターンにマッチする文字列のうち、もっとも短いものを指す
*/:任意の文字列の最後に/が来るパターン

※詳細はbashマニュアル参照

IFS(Internal Field Separator) 内部フィールド区切り文字

bash はスペースで単語を区切る
シェルスクリプト(特にbash)における「区切り文字」の役割を果たす特殊な変数
文字列を「どこで区切るか」を決めるための変数
デフォルト:スペース、タブ、改行
bash はコマンドライン引数や for 文の要素などを扱う際に単語を区切る必要がある場合は、IFS変数に含まれる文字を単語の区切りとみなす
※IFS を変更したら、終わったら元に戻すのがベスト

※スペースで区切らせないようにするには、IFSの値からスペースを抜いておく。

スペースを取り除く
// IFSに改行だけセットする
IFS='
'

シングルクォートで括った中に改行を入れることで、IFSに「改行」そのものを代入することができる。
※ bash では、$\n でも改行を表すことができる。

bash
IFS=$'\n'

IFSのバックアップ

IFSを変更すると、その以降の他のコマンドのどうさにも 影響を与えてしまう。
そのため、IFSを変更する際には、IFSを一旦別の変数にバックアップしておき、処理が終わった後に元に戻すのがよい。

IFSをバックアップしておく
_IFS=$IFS
IFS=$'\n'

... 処理

IFS=$_IFS

IFSの値は、文字コードを表示する od コマンドに、文字の名前で出力させる -a オプションをつけて確認することができる。

IFSの値の確認
echo -n "$IFS" | od -a

lsコマンドの出力結果でのスペースと改行

lsコマンドの出力では、ファイルの区切りはスペースと改行が入り混じっている。
すべてを改行区切りにしたい場合、 -1 オプションを利用して1ファイル1行で表示する必要がある。

lsコマンドは出力先がターミナルかどうかを自分で判断し、ファイルリストの出力形式を自動的に切り替えてくれるコマンドである
lsコマンドの結果をファイルへ出力リダイレクトしたり、コマンド置換によりlsコマンドを実行すると、lsコマンドは自動的に -1 オプションが付加されたときと同様に1ファイル1行で表示する。

ls -1: 各ファイルやディレクトリの名前を1行に表示するオプション

mabomabo

名前空間(namespace)

Linuxの名前空間は、システムリソースを論理的に分割し、プロセスグループごとに独立したリソース環境を提供する仕組み。
これにより、同じLinuxカーネル上で動く複数のプロセス群が、それぞれ異なる環境を持って動作しているように見せることができる。


https://8gwifi.org/docs/linux-namespace.jsp より画像引用

名前空間の目的
① プロセスごとに独立した環境(ファイルシステム、プロセスID、ネットワークなど)を提供し、他の名前空間の影響を受けずに動作可能にする。
② コンテナの基盤技術の一つ。DockerやKubernetesなどのコンテナ技術はこれを利用してプロセスを隔離。

主要な名前空間の種類と役割

名前空間名 リソース対象 概要
PID namespace プロセスID(PID) プロセスID空間を分離し、同じPIDを複数の名前空間で使えるように。コンテナ内のプロセスは自分だけのPID空間を持つ
NET namespace ネットワークインターフェース ネットワークデバイスやIPアドレス、ルーティングテーブルを分離。各名前空間ごとに独立したネットワーク環境を持つ
MNT namespace マウントポイント(ファイルシステム) ファイルシステムのマウント情報を分離。コンテナごとに異なるファイルシステム構成を持てる
UTS namespace ホスト名・ドメイン名 ホスト名やドメイン名を名前空間ごとに分けられる。コンテナごとに異なるホスト名を設定可能
IPC namespace プロセス間通信リソース System V IPC(セマフォ、メッセージキュー、共有メモリ)やPOSIXメッセージキューを分離
User namespace ユーザーID・グループID ユーザーとグループIDを名前空間ごとに分離。特にroot権限の扱いを分けられ、コンテナのセキュリティ強化に重要
Cgroup namespace cgroupsの階層表示 cgroups階層の情報を名前空間ごとに分離

・プロセスの完全な分離 → コンテナでの安全な動作を実現
・ネットワークの独立 → ネットワーク設定の衝突を防止
・ファイルシステムの分離 → コンテナごとに異なる環境を簡単に作成
・ユーザー権限の独立 → root権限の分離でセキュリティ向上

これにより、コンテナ内のプロセスはまるで独立したマシン上で動いているかのように見えるが、実は同じホストのカーネルを共有している。