← 戻る

cli/index

UNIX哲学・Bash・Git — エンジニアの右腕。"道具を理解せずして職人なし"

UNIX哲学

# Doug McIlroyが示し、半世紀後の今も現役の設計思想

1. 一つのことをうまくやれ

各プログラムは1つの仕事を完璧にこなす。grepは検索、sortは並び替え、wcは数える。

2. 連携できる形に作れ

テキストを共通言語に。プログラムの出力は他のプログラムの入力になる。

3. 早期に試作せよ

完璧を求めず動くものから。捨てる勇気を持て。

4. 効率より明瞭さ

巧妙さは敵。誰が読んでも分かるコードを。

"これがUNIX哲学である: 一つのことをうまくやるプログラムを書け。共に働くプログラムを書け。テキストストリームを扱うプログラムを書け。なぜならそれは普遍的なインターフェースだからだ。"— Doug McIlroy(UNIXパイプの発明者)

シェルとは何か

# OSとあなたの間に立つ通訳

キーボードで入力したコマンドを解釈し、OSに伝える対話インタフェース。代表的なものに sh, bash, zsh, fish, PowerShell

なぜ今でも必須なのか

必修コマンド30

# 一生使う基本道具

ファイル・ディレクトリ

ls -laファイル一覧(隠しファイル含む)
cd /pathディレクトリ移動
pwd現在地表示
mkdir -p a/b/c階層ディレクトリ作成
rm -rf dir削除(再帰・強制)※破壊的
cp -r src dstコピー(再帰)
mv old new移動・リネーム
ln -s target nameシンボリックリンク作成

表示・閲覧

cat file全表示
less fileページ送り表示(推奨)
head -n 20先頭20行
tail -f log末尾を追跡(ログ監視)
file xファイル種別判定
wc -l行数カウント

検索・テキスト

grep -rn "word" .テキスト検索(再帰・行番号)
find . -name "*.js"ファイル名検索
sed 's/old/new/g' f置換
awk '{print $2}' f列抽出・加工
sort | uniq -c重複カウント
cut -d, -f1 csvCSVの1列目
tr 'a-z' 'A-Z'大文字変換

ネットワーク・転送

curl -O urlURLダウンロード
wget url同上の代替
ssh user@hostリモート接続
scp file user@host:SSH経由コピー
rsync -avz s/ d/差分同期(最強)

プロセス・システム

ps aux | grep xプロセス検索
top / htopリアルタイム監視
kill -9 PIDプロセス強制終了
df -hディスク使用量
du -sh dirディレクトリサイズ
chmod 755 fパーミッション変更
rm -rf / は絶対NG — システム全削除。rm -rf $VAR/ も $VARが空だと同じ事故になる。--preserve-rootはデフォルトで有効だが慢心しないこと

パイプとリダイレクト — UNIXの心臓

# 小さな道具を組み合わせて巨大な仕事をする

基本記号

cmd1 | cmd2cmd1の出力をcmd2の入力に渡す(パイプ)
cmd > file標準出力をファイルへ(上書き)
cmd >> file追記
cmd 2> errエラー出力をファイルへ
cmd &> all両方をファイルへ
cmd < file標準入力をファイルから
cmd1 && cmd2cmd1成功時のみcmd2
cmd1 || cmd2cmd1失敗時にcmd2

定番ワンライナー

# アクセスログのIP上位10位
awk '{print $1}' access.log | sort | uniq -c | sort -rn | head -10

# プロジェクト全体のJSコード行数
find . -name "*.js" -not -path "*/node_modules/*" | xargs wc -l

# 大きいファイル上位20
du -ah . | sort -rh | head -20

# GitHub上で公開鍵を取得して登録
curl -s https://github.com/USER.keys >> ~/.ssh/authorized_keys

# 全ファイルから "TODO" を抽出して件数
grep -rn "TODO" --include="*.{js,ts,py}" . | wc -l

# プロセス重い順
ps aux --sort=-%cpu | head -10
"パイプは多くのコマンドの組み合わせを可能にする。これがUNIXを偉大にした。"— Doug McIlroy

Bashスクリプトの書き方

# 反復作業を自動化する芸術

セーフモード(必須)

#!/usr/bin/env bash
set -euo pipefail
# -e: エラーで即停止
# -u: 未定義変数でエラー
# -o pipefail: パイプ途中の失敗もキャッチ

IFS=$'\n\t'  # 区切り文字を厳格に

変数

name="世界"           # 代入は = の前後にスペース禁止
echo "こんにちは、$name"
echo "こんにちは、${name}さん"  # 推奨形

# コマンド置換
files=$(ls *.txt)

# 配列
arr=("a" "b" "c")
echo "${arr[0]}"     # a
echo "${arr[@]}"     # 全要素
echo "${#arr[@]}"    # 要素数

条件分岐

if [[ -f "$file" ]]; then
  echo "ファイル存在"
elif [[ -d "$file" ]]; then
  echo "ディレクトリ"
else
  echo "ない"
fi

# テスト演算子
# -f: ファイル存在  -d: ディレクトリ  -z: 空文字列  -n: 非空
# -eq -ne -lt -gt: 数値比較   ==/!=: 文字列比較

ループ

# forループ
for file in *.txt; do
  echo "処理中: $file"
done

# 数値範囲
for i in {1..10}; do
  echo "$i"
done

# whileループ(ファイルを行ごと)
while IFS= read -r line; do
  echo "行: $line"
done < input.txt

関数

greet() {
  local name="$1"
  echo "こんにちは、${name}さん"
}

greet "世界"
# 戻り値は echo で。return は終了コード(0-255)
必ず shellcheck でチェック。brew install shellcheck または shellcheck.net で即チェック

よくあるアンチパターン

Git 徹底解説

# Linus Torvaldsが2週間で書いた、人類の集団的記憶装置

Gitとは

分散型バージョン管理システム。誰がいつ何を変更したかを記録。リモート不要でローカルで完結し、ブランチで並行開発、マージで合流できる。

3つの場所を理解せよ

① Working Tree

普段編集している実ファイル

② Index (Staging)

次にコミットする内容の予告編。git addで進む

③ Repository

確定した履歴の倉庫。git commitで進む

必修コマンド

git init新規リポジトリ作成
git clone urlリモートをコピー
git status現在の状態確認(最頻出)
git add fileステージへ追加
git add -p変更を選択的にステージ(必修)
git commit -m "msg"コミット
git log --oneline --graph履歴をきれいに表示
git diff未ステージの差分
git diff --cachedステージ済み差分
git branchブランチ一覧
git switch -c new新ブランチ作成・切替
git merge featureマージ
git rebase main履歴をきれいに付け替え
git pullリモートから取得+マージ
git pushリモートに送信
git stash未コミット変更を一時退避
git restore file変更を取り消し
git restore --staged fステージング取り消し
git reset --soft HEAD~直前コミットを取り消し(変更は残す)
git reflog失った履歴の救命
git blame file誰がいつ書いたか
git bisectバグ混入コミットを二分探索
git cherry-pick HASH特定コミットを別ブランチに移植

ブランチ戦略

Git Flow

main / develop / feature / release / hotfix の5本立て。大規模/リリース管理が必要なときに。

GitHub Flow

main + featureブランチのみ。シンプル、CDの強い前提。スタートアップでよく見る。

Trunk Based

1本のmainに小さく頻繁にマージ。Google/Facebookが採用。

GitLab Flow

GitHub Flow + 環境ブランチ。staging/productionへの昇進を表現。

マージ vs リベース

git merge: 履歴を保持。マージコミットができる。共有ブランチに使う。
git rebase: 履歴を直線にする。ローカルブランチで使う。公開済みの履歴をrebaseするな

git push --force は劇薬 — 他人の履歴を消す可能性。--force-with-leaseを使え。mainブランチには絶対NG。

救済コマンド

# 直前のコミットメッセージ修正
git commit --amend

# 過去5コミットを整理(squash・並び替え)
git rebase -i HEAD~5

# コミットを失った!
git reflog
git reset --hard HEAD@{2}

# コミットしてはいけないファイルを履歴から消す
git filter-repo --invert-paths --path secrets.txt

# どのコミットでバグった?
git bisect start
git bisect bad HEAD
git bisect good v1.0
# Gitが二分探索で犯人を特定
"ファイルシステムが思想を持ったらこうなる。"— Linus Torvalds(Gitについて)

Vim の最小限の知識

# 出られないと話題のエディタの脱出方法

絶対覚える3つ

i挿入モードに入る(普通に編集できる)
Esc挿入モードを抜ける
:wq + Enter保存して終了
:q!変更を捨てて終了

使えると速くなる10選

h j k l左下上右に移動
w / b単語の先頭へ次/前
0 / $行頭/行末へ
gg / Gファイル先頭/末尾へ
dd1行削除
yy1行コピー
p貼り付け
uUndo
/word検索(n で次、N で前)
:s/old/new/g現在行で置換
:%s/old/new/gc全体置換(確認付き)

本気でVimを使うなら vimtutor コマンドを実行するのが最短。

必携モダンツール

# 一度使うと戻れなくなる近代版

ripgrep (rg)grep の高速代替。.gitignore準拠
fdfind の高速・簡単代替
batcat にシンタックスハイライト
eza / lsdls のカラフル代替
fzfあらゆる選択を高速インクリメンタルで
jqJSONを操作する sed/awk
yqYAMLの jq
htop / btoptop の見やすい代替
tldrman の実例特化版
zoxide (z)cd の学習型賢い版
tmuxセッション維持&分割
direnvディレクトリ毎に環境変数
mise / asdf言語ランタイム管理(Node/Python/Go等)
deltagit diff の超見やすい版
lazygitGit のTUI
ghGitHub CLI

シェル設定の鉄板(~/.bashrc / ~/.zshrc)

# 履歴を全タブで共有・大量保存
export HISTSIZE=50000
export HISTFILESIZE=100000
export HISTCONTROL=ignoredups:erasedups

# エイリアス
alias ll='eza -la --git'
alias g=git
alias gs='git status'
alias ..='cd ..'
alias ...='cd ../..'

# fzf統合(Ctrl-Rで履歴検索が劇的に進化)
eval "$(fzf --bash)"

# zoxide
eval "$(zoxide init bash)"

$ exit 0   最強のシェル使いになるまで、毎日少しずつ