web-dev-qa-db-ja.com

cdコマンドにフックできますか?

私が実行しているサーバーに何かを設定しようとしています。いつでもcdpublic_htmlフォルダ95%の場合、特定の項目をチェックするために常に実行するいくつかのコマンドがあります。

とにかくcdにフックできるので、ディレクトリがpublic_html、コマンドが自動的に実行されますか?

cdコマンドにフックできない場合、私が望んでいる結果を達成するために他に何かできることはありますか?

CentOS 5.8を実行しています。

9
TMH

この関数を.bashrcまたはその他の起動ファイル(シェルによって異なります)に追加できます。

cd() {      
   if [ "$1" = "public_html" ]; then
      echo "current dir is my dir"
   fi
   builtin cd "$1"
}
12
UVV

kshまたはbash(またはzsh)の場合:

cd() {
  builtin cd "$@" || return
  [ "$OLDPWD" = "$PWD" ] || case $PWD in
      (*/public_html) echo do something
    esac
}

zshの場合:

chpwd()
  case $PWD in
    (*/public_html) echo do something
  esac

chpwdhook関数であり、現在の作業ディレクトリが変更されるたびに呼び出されます(cdpushdpopd...))。

17

既存のコマンドであるcdをラップすることはお勧めしません。

より一般的なソリューションは、Bashでカスタムchpwdフックを定義することです。 (この質問のタグによると、あなたはBashを使用していると思います)

他の最新のシェルと比較すると、Bashで設計された完全なフックシステムはありません。 Prompt_COMMAND変数はフック関数として使用されます。これは、ZSHではprecmdフック、Fishではfish_Promptと同等です。とりあえず、chpwdフックが組み込まれているシェルはZSHだけです。

Prompt_COMMAND

設定されている場合、値は各プライマリプロンプト($ PS1)の印刷前に実行するコマンドとして解釈されます。

https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#Bash-Variables

chpwdバッシュのフック

Prompt_COMMANDに基づいてBashにchpwd同等のフックを設定するためのトリックが提供されています。

# create a PROPMT_COMMAND equivalent to store chpwd functions
typeset -g CHPWD_COMMAND=""

_chpwd_hook() {
  shopt -s nullglob

  local f

  # run commands in CHPWD_COMMAND variable on dir change
  if [[ "$PREVPWD" != "$PWD" ]]; then
    local IFS=$';'
    for f in $CHPWD_COMMAND; do
      "$f"
    done
    unset IFS
  fi
  # refresh last working dir record
  export PREVPWD="$PWD"
}

# add `;` after _chpwd_hook if Prompt_COMMAND is not empty
Prompt_COMMAND="_chpwd_hook${Prompt_COMMAND:+;$Prompt_COMMAND}"

PWDの変更を直接検出しているため、ソリューションはcdpushd、およびpopdで機能します。

:Bashのchpwd実装とZSHのchpwdの主な違いは、Prompt_COMMANDはサポートされていません非インタラクティブBashシェルで。

使用法

_public_html_action() {
  if [[ $PWD == */public_html ]]; then
    # actions
  fi
}

# append the command into CHPWD_COMMAND
CHPWD_COMMAND="${CHPWD_COMMAND:+$CHPWD_COMMAND;}_public_html_action"

出典: Bashでchpwdに相当するフックを作成 私の要旨から。

誰にとってもZSHの答えを求めています。 ZSHでchpwdフックを使用します。 chpwd()関数を直接定義しないでください。詳細はこちら

3
Simba

私はbashのエキスパートではありませんが、@ UVVの回答を少し修正して、次のようにします。

  • public_htmlをチェックする代わりに、ターゲットディレクトリhook-script、たとえば$1cd_hook.shファイルをチェックするだけです。
  • そのhook-scriptが存在する場合は、それを実行し、cdに進みます。

これにより、cd_hook.shをディレクトリに追加するだけで、cd- hookを任意のディレクトリに適用できるようになるため、より一般的なようです。

1
lost-and-found

Bashで強力なzshアプローチを使用する:

まずbashを拡張する簡単な方法:

〜/ .runscripts

#load all scripts inside $1 dir

run_scripts()
{
    for script in $1/*; do

        # skip non-executable snippets
        [ -f "$script" ] && [ -x "$script" ] || continue

        # execute $script in the context of the current Shell
        . $script
    done
}

.bashrcに含める:

. ~/.run_scripts

run_scripts ~/.bashrc.d

〜/ .bashrc.d/cdhookを作成するには:

#!/bin/bash

chpwd() {
  : #no action
}

cd() {      
   builtin cd $1
   chpwd $1
}

関数を置き換えるのはあなた次第です。

#list files after cd
chpwd() {
  ls -lah --color
}
0
albfan