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


9

実行しているサーバーに何かをセットアップしようとしcdていpublic_htmlます。常に95%の時間フォルダーに移動すると、特定のことを確認するために常に実行するコマンドがいくつかあります。

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

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

CentOS 5.8を実行しています。

回答:


12

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

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

おお、これは面白そうだ。これを.bash_profileに追加しecho "Testing..."、ifのすぐ上に追加しましたが、出力はありません。これらの変更を適用するために何かする必要がありますか?
TMH 2014年

@TomHart新しいセッションを開始しなかった場合は、次の方法で現在のセッションにファイルを読み込む必要があります. ~/.bash_profile
UVV '27

@TomHart /bin/cd私のCentOSにはないようなので、このソリューションは機能しない可能性があります
UVV '27

今気付いたばかりです。なぜunix.stackexchange.com/questions/116955/where-is-cd-locatedなのかを示すこの質問を見つけました。/ bin / cdが実際にあるシステムの場合でも、依然として優れたソリューションです:)。
TMH 2014年

1
あなたの場合は動作しませんcd -P public_htmlcd ~/public_htmlまたはあなたができない場合は、予期しない動作を持っているcdpublic_html
ステファンChazelas

17

kshbash(または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

chpwdあるフック現在の作業ディレクトリを介して(変更するたびに呼び出される関数cdpushdpopd...))。


3

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

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

他の最新のシェルと比較すると、Bashで設計された完全なフックシステムはありません。PROMPT_COMMAND変数は、FishのprecmdZSHのフックと同等のフック関数として使用されfish_promptます。とりあえず、ZSHは、フックが組み込まれている私が知っている唯一のシェルchpwdです。

PROMPT_COMMAND

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

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

chpwd バッシュのフック

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

# 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、直接変更を、解決策はで動作するcdpushdpopd

chpwdBashでの実装とchpwdZSHでの実装の主な違い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の答えを求めています。chpwdZSHでフックを使用します。関数を直接定義しないでくださいchpwd() 詳細はこちら


1

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

  • 代わりをチェックするpublic_html、私はいくつかをチェックしたいhook-scriptターゲット・ディレクトリ内のファイル$1、、と言いますcd_hook.sh
  • それがhook-script存在する場合は、それを実行し、次に進みますcd

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


3
それは一般的なようですが、セキュリティの脆弱性を導入しています。誰かが何かをする必要があるのは、たとえば/ tmpにフックスクリプトを組み込んで、次にcdを実行するときにコードを実行できるようにするだけです。少なくとも、フックスクリプトがシンボリックリンクではなく自分によって所有され、自分以外の誰からも書き込みができないようにし、それが含まれているディレクトリが自分だけが書き込み可能であることを確認する必要があります... 作業ディレクトリごとの履歴の保持を参照してください。(シェルセッションごとに参照)より安全なアプローチ。
ステファンChazelas

セキュリティの洞察力@StéphaneChazelasをありがとう。私はそれについて考えさえしなかったことを認めなければなりません。
遺失物

私はそれをしているときにこの質問を見つけました:cdどこかにいる場合は、.bashcdファイルを確認して、存在する場合は実行します。
DarkWiiPlayer 2018

0

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
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.