क्या मैं सीडी कमांड में हुक लगा सकता हूं?


9

मैं एक सर्वर पर चलने के लिए कुछ स्थापित करने की कोशिश कर रहा हूं, जब मैं कभी-कभी 95% फ़ोल्डर cdमें public_htmlहोता हूं तो कुछ कमांड हैं जो मैं हमेशा कुछ चीजों की जांच करने के लिए चलाऊंगा।

वैसे भी क्या मैं हुक कर सकता हूं 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, लेकिन nothings आउटपुट के ठीक ऊपर जोड़ा है । क्या मुझे इन परिवर्तनों को लागू करने के लिए कुछ करने की आवश्यकता है?
टीएमएच

@TomHart यदि आपने एक नया सत्र शुरू नहीं किया है, तो आपको अपने वर्तमान सत्र में फ़ाइल का स्रोत बनाना होगा. ~/.bash_profile
UVV

@TomHart ऐसा लगता है कि /bin/cdमेरे CentOS में कोई नहीं है, इसलिए यह समाधान काम नहीं करने वाला है
UVV

मैंने अभी गौर किया है। मुझे यह सवाल मिला, जो बताता है कि क्यों unix.stackexchange.com/questions/116955/where-is-cd-located । अभी भी सिस्टम के लिए एक अच्छा समाधान है जो वास्तव में एक / बिन / सीडी है :)।
टीएमएच

1
काम नहीं करता है अगर आप cd -P public_htmlया cd ~/public_htmlया अनपेक्षित व्यवहार करता है, तो आप कर सकते हैं नहीं है cdमें public_html
स्टीफन चेज़लस

17

साथ 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

( chpwdएक है हुक समारोह में कहा जाता है कि जब भी वर्तमान कार्यशील निर्देशिका के माध्यम से बदल जाता है ( cd, pushd, popd...))।


3

रैपिंग cd, एक मौजूदा कमांड, अनुशंसित नहीं है।

एक अधिक सार्वभौमिक समाधान chpwdबैश में एक कस्टम हुक को परिभाषित करेगा । (इस सवाल के टैग के अनुसार, मुझे लगता है कि आप बैश का उपयोग कर रहे हैं)

अन्य आधुनिक गोले की तुलना में बाश में डिजाइन किया गया एक पूर्ण हुक सिस्टम नहीं है। PROMPT_COMMANDचर का उपयोग एक हुक फ़ंक्शन के रूप में किया जाता है, जो मछली precmdमें ज़ेडएसएच में हुक के बराबर होता है fish_prompt। कुछ समय के लिए, ZSH एकमात्र शेल है जिसे मैंने जाना है जिसमें एक chpwdहुक बिलिन है।

PROMPT_COMMAND

यदि सेट किया जाता है, तो मूल्य को प्रत्येक प्राथमिक संकेत ($ PS1) की छपाई से पहले निष्पादित करने के लिए एक कमांड के रूप में व्याख्या की जाती है।

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

chpwd बाश में हुक

chpwdबैश के आधार पर समतुल्य हुक को स्थापित करने के लिए एक ट्रिक प्रदान की जाती है 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सीधे परिवर्तन, समाधान के साथ काम करता है cd, pushdऔर popd

नोट : chpwdबैश और chpwdज़ेडएस में हमारे कार्यान्वयन के बीच मुख्य अंतर PROMPT_COMMANDगैर-इंटरैक्टिव बैश शेल में समर्थित नहीं है।

प्रयोग

_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"

स्रोत: मेरी मुट्ठी से बैश में chpwd समतुल्य हुक बनाएँ

किसी के लिए भी ZSH का जवाब चाहिए। chpwdZSH में हुक का उपयोग करें । सीधे कार्य को परिभाषित न करें chpwd() यहाँ और अधिक विस्तार


1

मैं एक बैश विशेषज्ञ नहीं हूं, लेकिन मैं @ UVV का उत्तर लेता हूं और इसे थोड़ा संशोधित करता हूं ताकि यह ऐसा हो:

  • के बजाय जाँच के लिए public_html, मैं बस hook-scriptलक्ष्य dir में कुछ फ़ाइल के लिए जाँच करेंगे $1, कहते हैं cd_hook.sh,।
  • यदि वह hook-scriptमौजूद है, तो उसे चलाएं, और उसके साथ आगे बढ़ेंcd

यह अधिक सामान्य लगता है क्योंकि आप तब cdकिसी भी निर्देशिका में -hook लागू करने में सक्षम होंगे यदि आप ऐसा चुनते हैं, तो बस cd_hook.shउक्त निर्देशिका में एक जोड़कर ।


3
यह सामान्य लगता है, लेकिन आप सुरक्षा भेद्यता का परिचय दे रहे हैं। किसी को या किसी को केवल उदाहरण के लिए / tmp में एक हुक-स्क्रिप्ट लगाने की ज़रूरत होती है ताकि आप अगली बार जब भी आप वहाँ cd चला सकें। आप कम से कम यह सुनिश्चित करना चाहेंगे कि हुक-स्क्रिप्ट आपके स्वामित्व में हो, सिम्क्लिन नहीं, आपके अलावा किसी अन्य द्वारा लिखित नहीं, कि यह जिस निर्देशिका में है, वह आपके द्वारा केवल लेखन योग्य है ... प्रति कार्यशील इतिहास देखें (cf. प्रति शेल सत्र) सुरक्षित दृष्टिकोण के लिए।
स्टीफन चेज़लस

सुरक्षा जानकारी के लिए धन्यवाद @ StéphaneChazelas। मुझे मानना ​​पड़ेगा कि मैंने इसके बारे में सोचा भी नहीं था।
खोया-पाया

मुझे यह सवाल सिर्फ यह करते हुए मिला: अगर मैं cdकहीं हूं , तो .bashcdफ़ाइल की जांच करें और यदि मौजूद है तो उसे चलाएं।
DarkWiiPlayer

0

बाश में शक्तिशाली zsh दृष्टिकोण का उपयोग करना:

बैश का विस्तार करने का पहला आसान तरीका:

~ / .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
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.