$ PWD में किसी भी बदलाव के बाद मैं bash में कमांड कैसे चला सकता हूं?


10

zsh कुछ अच्छा प्रदान करता है हुक कार्यों सहित chpwdएक समारोह चल उपयोगकर्ता निर्देशिका में परिवर्तन के बाद के लिए।

# zsh only
function greet() { echo 'hi'; }
chpwd_functions+=("greet")
cd .. # hi
pushd # hi
popd  # hi

मुझे लगता है कि कोस में अनुकरण करने की कोशिश कर रहा हूँ।

प्रतिबंध:

  • यह संवादात्मक और गैर-संवादात्मक दोनों प्रकार के गोले में काम करना चाहिए, जो मुझे लगता है कि इसका मतलब है कि यह किसी चीज़ पर भरोसा नहीं कर सकता है $PROMPT_COMMAND
  • इसे फिर से परिभाषित नहीं किया जा सकता है cd, क्योंकि मैं चाहता हूं कि यह किसी भी कमांड के लिए काम करे जो निर्देशिकाओं को बदलता है (उदाहरण के लिए, pushdऔर popd)
  • यह चलाना चाहिए के बाद , उपयोगकर्ता के आदेश तो trap "my_function" DEBUG, नहीं, काम करता है जब तक कि मैं किसी भी तरह वहाँ में कह सकते हैं "पहली चलाने $BASH_COMMAND, हम फंस तो भी ऐसा कर ..." मुझे लगता है कि मैं स्वत: चल रहा से बचने कर सकते की $BASH_COMMAND यदि extdebug सक्षम किया गया है और ट्रैप फ़ंक्शन 1 लौटाता है, लेकिन मुझे नहीं लगता कि मैं मजबूर करना चाहता हूं extdebug, और 1एक सफल (लेकिन संशोधित) कमांड के लिए वापस लौटना गलत लगता है।

अंतिम भाग - "उपयोगकर्ता की आज्ञा के बाद चलाएं" - जो वर्तमान में मुझे स्टम्प्ड किया गया है। अगर मैं प्रत्येक कमांड के बाद एक फ़ंक्शन चला सकता हूं , तो मैं यह जांच कर सकता हूं कि क्या हमने पिछली बार जांच के बाद निर्देशिका बदल दी है। उदाहरण के लिए:

function check_pwd() {
  # true in a new shell (empty var) or after cd
  if [ "$LAST_CHECKED_DIR" != "$PWD" ]; then
    my_function
  fi
  LAST_CHECKED_DIR=$PWD
}

क्या मैं सही रास्ते पर हूँ, या एक बेहतर तरीका है? उपयोगकर्ता निर्देशिकाओं को बदलने के बाद मैं कैसे bash में कमांड चला सकता हूं?


3
क्यों फिर से परिभाषित नहीं cd, pushdऔर popd? डायरेक्टरी बदलने के और कितने तरीके हैं?
jw013

@ jw013 इस कोड का उद्देश्य एक ओपन सोर्स प्रोजेक्ट में जाना है, जहाँ अनुरक्षक ने विशेष cdरूप से एक सिद्धांत के रूप में पुनर्परिभाषित नहीं किया है।
नाथन लॉन्ग

इसके अलावा - "डायरेक्टरी बदलने के लिए और कितने तरीके हैं" - मुझे नहीं पता, जो एक और कारण है कि मैं उन्हें स्पष्ट रूप से सूचीबद्ध करने पर भरोसा नहीं करना चाहूंगा।
नाथन लॉन्ग

तुम ऐसा क्यों करना चाहते हो? आपका कार्य बहुत सारे कार्यक्रमों (सी, जावा, ..) को तोड़ सकता है। जिन लिपियों में मैं उपयोग करता हूं MYBIN=$( cd -P -- "$(dirname -- "$(command -v -- "$0")")" && pwd -P )कृपया उन विश्वसनीय यूनिक्स कमांड को न बदलें।
वाल्टर ए

1
@NathanLong केवल मेरे ऑपरेटिंग सिस्टम के लिए है । ऑपरेटिंग सिस्टम यहाँ अप्रासंगिक लगता है। OS क्या मायने रखता है? यह वह शेल है जो आपके प्रश्न में मायने रखता है, और आप विशेष रूप से इस बारे में पूछते प्रतीत होते हैं bash, जो सभी ऑपरेटिंग सिस्टमों पर समान रूप से काम करता है।
jw013

जवाबों:


2

कोई रास्ता नहीं है जो इन बाधाओं को पूरा करता है

ऐसा लगता है कि मेरी बाधाओं के साथ टकराव में इस समस्या को हल करने का कोई तरीका नहीं है। सामान्य तौर पर, संभव समाधान हैं:

  • ओवरराइड cd, pushdऔर popd, ताकि निर्देशिकाओं को बदलने वाली कोई भी कमांड पहले हुक फ़ंक्शन को चलाएगी। लेकिन इससे समस्याएं पैदा हो सकती हैं क्योंकि 1) ओवरराइड को मूल कमांड की तरह पूरा करने के लिए सावधान रहना चाहिए और उसी एग्जिट कोड और 2 को वापस करना होगा) यदि एक से अधिक उपकरण इस दृष्टिकोण को लेते हैं, तो वे एक साथ अच्छा नहीं खेल सकते हैं
  • पहले हुक फ़ंक्शन को चलाने के लिए पर्यावरण परिवर्तन के साथ चलाए जा सकने वाले सभी आदेशों को ओवरराइड करें। यह कठिन है क्योंकि ऐसे कई आदेश हैं
  • trap 'my_functionDEBUG so that every command will run the hook function. This is suboptimal because 1) it runs before every command, 2) it runs *before*cd`, 3 के बाद नहीं) केवल एक डिबग फ़ंक्शन हो सकता है, इसलिए यदि कोई अन्य उपकरण इस दृष्टिकोण का उपयोग करता है, तो वे एक साथ नहीं खेल सकते हैं
  • $PROMPT_COMMANDपहले हुक फ़ंक्शन को चलाने के लिए फिर से परिभाषित करें। यह अडॉप्टिमल है क्योंकि यह गैर-संवादात्मक गोले में काम नहीं करेगा, और क्योंकि यदि कोई अन्य उपकरण प्रॉम्प्ट कमांड को परिभाषित करता है, तो वे एक साथ अच्छा नहीं खेल सकते हैं।

संक्षेप में ऐसा लगता है कि एकमात्र महान समाधान होगा यदि बैश zshell के chpwd_functionsहुक की तरह कुछ प्रदान किया जाए , लेकिन यह ठीक से अनुकरण करना असंभव लगता है।


1

यदि अनुचर आपको सीडी के लिए परिभाषा बदलना पसंद नहीं करता है, तो एक और विकल्प उन सभी कमांडों को फिर से परिभाषित करना होगा जो इस-डायरेक्टरी का उपयोग करते हैं:

for c in cmd1 cmd2 cmd3 cmd4 cmd5 ; do
    eval "$c() { check_pwd ; command $c \"\$@\" ; }"
done

यह काफी कुशल होगा क्योंकि पीडब्ल्यूडी हुक और इन-डायरेक्टरी कॉन्फिगरेशन को केवल तभी प्रोसेस किया जाएगा जब आवश्यकता होगी।

आपके उदाहरण में check_pwd फ़ंक्शन, मैं बदल सकता हूं:

my_function

सेवा:

my_function "$PWD"

नए cwd में पास होने के लिए (अधिक मॉड्यूलर, परीक्षण योग्य हो सकता है)।


"इन-डायरेक्टरी वातावरण का उपयोग करने वाले सभी आदेशों को फिर से परिभाषित करें" दुर्भाग्य से, मैं इसकी भविष्यवाणी नहीं कर सकता।
नाथन लॉन्ग

0

अपने वितरण के अनुसार inotify-tools स्थापित करें ।

inotifywait -emodify,create,delete -m /path/to/directory | while read line; do service httpd reload; done

मेरे उदाहरण में, httpdयदि निर्दिष्ट निर्देशिका में कुछ भी परिवर्तन (संशोधित करें, बनाएं, हटाएं) करें तो निम्नलिखित कमांड पुनः आरंभ होगा ।

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