bash

関数ラッピング

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 ~]$

スポンサーリンク
タイトルとURLをコピーしました