リダイレクトで上書き事故が起きる仕組み
シェルの出力リダイレクト演算子 > は、コマンドの標準出力をファイルへ書き込むために広く使われます。しかしこの演算子には、指定したファイルがすでに存在していても警告を出さずに中身を消去・上書きするという性質があります。
典型的な事故のパターンとして、追記のつもりで >> と書くべきところを > と書いてしまうケースがあります。ファイル名を少し打ち間違えて、別の重要なファイルを上書きしてしまうことも起こりえます。このような事故はコマンドを実行した直後に気づきにくく、バックアップがなければ復旧が困難です。
こうした事故を防ぐ手段として、多くのシェルには noclobber(ノークロバー)オプションが用意されています。有効にすると、> で既存ファイルへの上書きを試みたときにエラーを出して処理を止めてくれます。
noclobberオプションを有効にする
bash と zsh のどちらでも noclobber オプションを利用できます。まずは現在のシェルセッションで試してみましょう。
bashの場合
以下のいずれかを実行します。
set -o noclobber
短縮形も用意されています。
set -C
zshの場合
setopt noclobber
zsh でも set -o noclobber や set -C で同じ効果が得られます。
設定が効いているか確かめる
テスト用のファイルを作成してから上書きを試みることで、動作を確認できます。
# テスト用ファイルを作成する
echo "original" > /tmp/testfile.txt
# noclobber を有効にする(bashの場合)
set -o noclobber
# 上書きを試みる
echo "overwrite" > /tmp/testfile.txt
noclobber が有効になっていれば、次のようなエラーが出力されます。
bash: /tmp/testfile.txt: cannot overwrite existing file
このエラーが表示されれば、設定は正しく機能しています。ファイルの内容が元のままであることは、次のコマンドで確認できます。
cat /tmp/testfile.txt
original と表示されれば、上書きが防がれています。
設定を永続化する(ログイン後も有効にする)
set -o noclobber はそのシェルセッション限りで有効です。ターミナルを閉じると設定はリセットされます。ログインのたびに自動で有効にするには、シェルの設定ファイルへ追記します。
bashを使っている場合
echo "set -o noclobber" >> ~/.bashrc
追記後、現在のセッションへ即座に反映するには次を実行します。
source ~/.bashrc
zshを使っている場合
echo "setopt noclobber" >> ~/.zshrc
source ~/.zshrc
エディタで設定ファイルを直接開いて追記する方法でもかまいません。設定が反映されたかどうかは、前述のテスト手順で確かめられます。
noclobber有効時に上書きしたいときは
noclobber を有効にしていても、意図的に既存ファイルを上書きしたい場面はあります。そのようなときは >|(大なり記号とパイプを続けて書く)を使います。
# noclobberが有効でも強制的に上書きする
echo "new content" >| /tmp/testfile.txt
>| は「noclobber の制限を一時的に無視して上書きする」演算子です。bash・zsh のどちらでも利用できます。一時的に noclobber 自体を解除したい場合は次のコマンドを使います。
# bashの場合
set +o noclobber
# zshの場合
unsetopt noclobber
解除はそのセッション内でのみ有効で、設定ファイルは変更されません。
よくあるつまずき
シェルスクリプト内では引き継がれない
~/.bashrc に noclobber を設定しても、シェルスクリプト(.sh ファイル)の中では有効になりません。スクリプト内でもファイルの上書きを防ぎたい場合は、スクリプトの先頭に明示的に記述します。
#!/bin/bash
set -o noclobber
rootユーザーには別途設定が必要
一般ユーザーの ~/.bashrc に設定しても、sudo -i や su - で root へ切り替えると別の設定ファイルが読み込まれるため、noclobber は引き継がれません。root でも有効にしたい場合は /root/.bashrc にも同様に追記します。
追記(>>)は制限の対象外
noclobber が防ぐのは > による上書きだけです。>>(追記)は制限の対象外で、noclobber を有効にしていても通常通り利用できます。追記操作を誤って上書きにしてしまう事故を防ぎたいという用途では、入力時の注意が必要な点に変わりはありません。
同名ファイルを新規作成するスクリプトでエラーになる場合がある
noclobber を有効にした環境では、「既存ファイルを削除してから同名ファイルへ書き出す」処理をひとつのスクリプト内で行う場合でも、> の直前に削除が完了していれば問題ありません。ただし、ファイルが残った状態で > を実行する設計になっているスクリプトでは意図せずエラーが出ることがあります。この場合は >| を使うか、処理の順序を見直します。
「コマンドは打てる。次は”現場で通用する型”を最短で身につけたい」——そんなあなたへ。
ネットの断片的なTipsをコピペするだけでは、体系的な運用スキルはなかなか積み上がりません。リナックスマスター.JPの無料メルマガ「リナマガ」では、現場で実際に使うLinuxサーバー運用の考え方を、順を追って実務目線でお届けしています。いま登録された方には、安全なサーバー構築の「型」をまとめた『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼント中です。
>> 図解60P『Linux入門マニュアル』を無料で受け取る
(メルマガ登録は10秒・いつでも解除OK)
※ 「独学の時間がもったいない」「プロから現場の技術を最短で学びたい」という本気の方には、2日で実務レベルが身につく初心者向けハンズオンセミナーもご用意しています。
