リンクの基本概念
Linuxには2種類のリンクがあります:
ハードリンク
- 同じiノード(実際のデータ)を指す別名
- 元ファイルと区別がつかない
- 同じファイルシステム内でのみ作成可能
シンボリックリンク(ソフトリンク)
- 別のファイルやディレクトリへのパスを含む特殊ファイル
- Windowsのショートカットに似ている
- ファイルシステムをまたいで作成可能
ハードリンクの作成と理解
CommandAcademy Terminal
Welcome to CommandAcademy Terminal!
Type "help" to see available commands.
user@cmdac:~$
█
ファイルツリー
/
etc
hosts35B
passwd76B
home
user
tmp
usr
bin
share
var
log
ハードリンクの特徴:
ls -li
でiノード番号を確認できる- リンクカウントが増える
- どちらが「オリジナル」か区別できない
- ディレクトリには作成できない(通常)
ハードリンクの作成
# ハードリンクの作成
ln original.txt hardlink.txt
# iノード番号の確認
ls -li original.txt hardlink.txt
# 内容の確認
cat hardlink.txt
# 片方を編集すると両方に反映
echo "Modified content" > original.txt
cat hardlink.txt
ハードリンクの特性
CommandAcademy Terminal
Welcome to CommandAcademy Terminal!
Type "help" to see available commands.
user@cmdac:~$
█
ファイルツリー
/
etc
hosts35B
passwd76B
home
user
tmp
usr
bin
share
var
log
# リンクカウントの確認
ls -l file.txt
# 第2フィールドがリンクカウント
# 1つ削除してもデータは残る
rm file.txt
ls -l link1.txt # まだアクセス可能
# すべてのリンクを削除するとデータも削除
rm link1.txt link2.txt
シンボリックリンクの作成と管理
CommandAcademy Terminal
Welcome to CommandAcademy Terminal!
Type "help" to see available commands.
user@cmdac:~$
█
ファイルツリー
/
etc
hosts35B
passwd76B
home
user
tmp
usr
bin
share
var
log
シンボリックリンクの作成:
ln -s target link_name
-s
オプションが重要!忘れるとハードリンクになります。
シンボリックリンクの基本操作
# ファイルへのシンボリックリンク
ln -s /tmp/test/dir1/file.txt mylink.txt
# ディレクトリへのシンボリックリンク
ln -s /tmp/test/dir1 mydir
# リンクの確認
ls -l mylink.txt mydir
# リンク先の確認
readlink mylink.txt
readlink -f mylink.txt # 絶対パス
# リンクをたどる
cat mylink.txt
cd mydir
相対パスと絶対パス
CommandAcademy Terminal
Welcome to CommandAcademy Terminal!
Type "help" to see available commands.
user@cmdac:~$
█
ファイルツリー
/
etc
hosts35B
passwd76B
home
user
tmp
usr
bin
share
var
log
# 絶対パスでリンク
ln -s /home/user/project/src/app.py /usr/local/bin/myapp
# 相対パスでリンク(推奨)
cd project/bin
ln -s ../src/app.py myapp
# 相対リンクの利点:ディレクトリ移動後も有効
cd ../..
mv project project_renamed
ls -l project_renamed/bin/myapp # まだ有効
リンクの実践的な使用例
1. 設定ファイルの管理
CommandAcademy Terminal
Welcome to CommandAcademy Terminal!
Type "help" to see available commands.
user@cmdac:~$
█
ファイルツリー
/
etc
hosts35B
passwd76B
home
user
tmp
usr
bin
share
var
log
# dotfilesリポジトリの管理
ln -s ~/dotfiles/bashrc ~/.bashrc
ln -s ~/dotfiles/vimrc ~/.vimrc
ln -s ~/dotfiles/gitconfig ~/.gitconfig
# 複数環境での設定切り替え
ln -sf configs/dev.conf app.conf # 開発環境
ln -sf configs/prod.conf app.conf # 本番環境
2. ディスク容量の節約
# 大きなファイルの共有
ln large_dataset.csv /project1/data.csv
ln large_dataset.csv /project2/data.csv
# 重複ファイルの統合
# ハードリンクで置き換え
find . -type f -exec md5sum {} + | sort | uniq -d -w32
3. バージョン管理
CommandAcademy Terminal
Welcome to CommandAcademy Terminal!
Type "help" to see available commands.
user@cmdac:~$
█
ファイルツリー
/
etc
hosts35B
passwd76B
home
user
tmp
usr
bin
share
var
log
# 現在のバージョンへのリンク
ln -sf versions/app-v2.0.jar app-current.jar
# バージョンアップ時
ln -sf versions/app-v2.1.jar app-current.jar
# ロールバック
ln -sf versions/app-v2.0.jar app-current.jar
リンクの検索と管理
findを使ったリンクの検索
CommandAcademy Terminal
Welcome to CommandAcademy Terminal!
Type "help" to see available commands.
user@cmdac:~$
█
ファイルツリー
/
etc
hosts35B
passwd76B
home
user
tmp
usr
bin
share
var
log
# シンボリックリンクを検索
find . -type l
# 壊れたシンボリックリンクを検索
find . -xtype l
# 特定のファイルへのハードリンクを検索
find . -samefile file2.txt
# シンボリックリンクの詳細表示
find . -type l -ls
リンクの修復と削除
# 壊れたリンクの削除
find . -xtype l -delete
# リンク先の変更
ln -sfn new_target existing_link
# リンクのみ削除(リンク先は残る)
rm symlink
# または
unlink symlink
高度なリンク管理
リンクのコピーと移動
CommandAcademy Terminal
Welcome to CommandAcademy Terminal!
Type "help" to see available commands.
user@cmdac:~$
█
ファイルツリー
/
etc
hosts35B
passwd76B
home
user
tmp
usr
bin
share
var
log
# シンボリックリンクとしてコピー
cp -P source/link.txt dest/
# リンク先の実体をコピー
cp -L source/link.txt dest/
# ディレクトリ構造を保持してコピー
cp -a source/ dest/
# rsyncでリンクを保持
rsync -avl source/ dest/
スクリプトでのリンク処理
#!/bin/bash
# リンクを安全に作成するスクリプト
create_safe_link() {
local target=$1
local link=$2
# 既存のリンクや ファイルをバックアップ
if [ -e "$link" ]; then
mv "$link" "${link}.bak"
fi
# リンク作成
ln -s "$target" "$link"
# 検証
if [ -L "$link" ] && [ -e "$link" ]; then
echo "Link created successfully"
else
echo "Failed to create link"
return 1
fi
}
実践演習
演習1:開発環境の構築
CommandAcademy Terminal
Welcome to CommandAcademy Terminal!
Type "help" to see available commands.
user@cmdac:~$
█
ファイルツリー
/
etc
hosts35B
passwd76B
home
user
tmp
usr
bin
share
var
log
複数のプロジェクトで共通のnode_modulesを共有する構造を作成してください。
解答例:
# 共有モジュールの設定
cd ~/shared_modules
npm install express mongoose
# 各プロジェクトでリンク
cd ~/projects/project1
rm -rf node_modules
ln -s ~/shared_modules node_modules
cd ~/projects/project2
rm -rf node_modules
ln -s ~/shared_modules node_modules
# 確認
ls -la ~/projects/*/node_modules
演習2:設定ファイルの環境切り替え
CommandAcademy Terminal
Welcome to CommandAcademy Terminal!
Type "help" to see available commands.
user@cmdac:~$
█
ファイルツリー
/
etc
hosts35B
passwd76B
home
user
tmp
usr
bin
share
var
log
環境に応じて設定ファイルを切り替えるシステムを構築してください。
解答例:
cd app
# 各環境の設定作成
echo 'DEBUG=true' > config/dev/.env
echo 'DEBUG=false' > config/staging/.env
echo 'DEBUG=false' > config/prod/.env
# 切り替えスクリプト
cat > switch_env.sh << 'EOF'
#!/bin/bash
ENV=$1
if [ -d "config/$ENV" ]; then
ln -sfn "config/$ENV/.env" .env
echo "Switched to $ENV environment"
else
echo "Environment $ENV not found"
fi
EOF
chmod +x switch_env.sh
# 使用例
./switch_env.sh dev
./switch_env.sh prod
トラブルシューティング
よくある問題と解決策
1. シンボリックリンクが機能しない
# 相対パスの問題
# 悪い例
ln -s file.txt /other/dir/link.txt # file.txtが見つからない
# 良い例
ln -s /full/path/to/file.txt /other/dir/link.txt
# または
cd /other/dir && ln -s /full/path/to/file.txt link.txt
2. 循環参照
# 循環参照の検出
find -L . -type l
# 最大深度を制限
find -L . -maxdepth 10 -type d
3. パーミッションの問題
# リンク自体のパーミッションは関係ない
# リンク先のパーミッションが重要
chmod 777 symlink # 効果なし
chmod 755 $(readlink -f symlink) # リンク先を変更
セキュリティの考慮事項
リンクに関するセキュリティ
# シンボリックリンク攻撃の防止
# /tmpでの安全なファイル作成
mktemp -d
# リンクをたどらないオプション
tar --no-recursion -czf archive.tar.gz directory/
# リンクの検証
[ -L "$file" ] && echo "This is a symbolic link"
[ -e "$file" ] || echo "Broken link"
まとめ
このレッスンでは、リンクシステムについて学びました:
- ハードリンクとシンボリックリンクの違い
- 各リンクタイプの適切な使用場面
- リンクを使った効率的なファイル管理
- リンクに関するトラブルシューティング
リンクを適切に使用することで、ディスク容量の節約と柔軟なファイル管理が可能になります。
💡 次のレッスンでは、ファイルシステムとマウントについて学びます。