bashコマンドには優先順位があり最も関数が優先されます。
関数→組込みコマンド(builtin)→alias→外部コマンド(path登録したスクリプト)
この特徴を生かし以下のような事ができます。
危険なコマンド実行前に確認を入れる
rm() {
# 全ての引数($*)を合体させた文字列
local args="$*"
# ==================================================
# パターンA:最凶(-r と -f が両方ある場合)
# ==================================================
if [[ "$args" =~ -[a-zA-Z]*r[a-zA-Z]*f || "$args" =~ -[a-zA-Z]*f[a-zA-Z]*r || ("$args" =~ -[a-zA-Z]*r && "$args" =~ -[a-zA-Z]*f) ]]; then
echo -e "==========【超厳重警告!!】==============="
echo -e "再帰的かつ強制的な削除 (rm -rf / -fr) が検知されました"
echo "実行しようとしたコマンド: rm $args"
echo "--------------------------------------------------"
read -p "【警告】本当に全てを失う覚悟はありますか? (y/N): " choice
if [[ "$choice" != "y" ]]; then
echo -e "処理を安全に中断しました。"
return 1
fi
# ==================================================
# パターンB:中間(-r 単体:ディレクトリごと削除の場合)
# ==================================================
elif [[ "$args" =~ -[a-zA-Z]*r ]]; then
echo -e "=======【警告:ディレクトリ削除】 ============"
echo "ディレクトリ構造をまとめて削除しようとしています。"
echo "実行しようとしたコマンド: rm $args"
echo "--------------------------------------------------"
read -p "フォルダごと削除してよろしいですか? (y/N): " choice
if [[ "$choice" != "y" ]]; then
echo -e "処理を中断しました。\n"
return 1
fi
# ==================================================
# パターンC:中間(-f 単体:警告なし強制削除の場合)
# ==================================================
elif [[ "$args" =~ -[a-zA-Z]*f ]]; then
echo -e "========== 【警告:強制削除】============"
echo "確認なしの強制削除オプション (-f) が指定されています。"
echo "実行しようとしたコマンド: rm $args"
echo "--------------------------------------------------"
read -p "本当に強制削除しますか? (y/N): " choice
if [[ "$choice" != "y" ]]; then
echo -e "処理を中断しました。\n"
return 1
fi
fi
# 安全確認をすべてパスしたら、本物のrmスクリプトに丸投げ
command rm "$@"
}
組込み関数(builtin)を置き換える場合
# 1. 本物の「cd」コマンドを、別名(__real_cd)として退避させてキープする
alias __real_cd='builtin cd'
# 2. 本物と同じ「cd」という名前で、新しく身代わり関数を定義する(上書き・すり替え)
cd() {
# --- 前処理 ---
echo "ディレクトリを移動します..."
# 退避させておいた本物のcd(__real_cd)に、引数($@)を丸投げして実行!
__real_cd "$@"
# --- 後処理 ---
echo "移動先の中身を表示します:"
ls -F
}
登録した関数のクリア
unset -f cd
動作例
# type コマンドで実態は何か確認できます。
#
[sooni@localhost ~]$ type cd
cd はシェル組み込み関数です
# 関数によるラッピング
#
[sooni@localhost ~]$ # 1. 本物の「cd」コマンドを、別名(__real_cd)として退避させてキープする
alias __real_cd='builtin cd'
# 2. 本物と同じ「cd」という名前で、新しく身代わり関数を定義する(上書き・すり替え)
cd() {
# --- 前処理 ---
echo "ディレクトリを移動します..."
# 退避させておいた本物のcd(__real_cd)に、引数($@)を丸投げして実行!
__real_cd "$@"
# --- 後処理 ---
echo "移動先の中身を表示します:"
ls -F
}
# 確認
#
[sooni@localhost ~]$ type cd
cd は関数です
cd ()
{
echo "ディレクトリを移動します...";
builtin cd "$@";
echo "移動先の中身を表示します:";
ls --color=auto -F
}
# 実際に動作確認
#
[sooni@localhost ~]$ cd testdir/
ディレクトリを移動します...
移動先の中身を表示します:
deploy.sh* tt
# 元に戻す
#
[sooni@localhost testdir]$ unset -f cd
[sooni@localhost testdir]$ type cd
cd はシェル組み込み関数です
[sooni@localhost testdir]$ cd
[sooni@localhost ~]$
