हैश कमांड का उद्देश्य क्या है?


116

यदि आप hashइसे चलाते हैं तो हैश के अंतिम रीसेट ( hash -r) के बाद से चलने वाले सभी कमांड का रास्ता दिखाता है

[root@c04c ~]# hash
hash: hash table empty

[root@c04c ~]# whoami
root

[root@c04c ~]# hash
hits    command
   1    /usr/bin/whoami

[root@c04c ~]# whoami
root

[root@c04c ~]# hash
hits    command
   2    /usr/bin/whoami

मैन पेजों के अनुसार, हैश का उद्देश्य है:

/ Usr / bin / hash उपयोगिता वर्तमान शेल पर्यावरण के उपयोगिताओं के स्थानों को याद करने के तरीके को प्रभावित करती है। निर्दिष्ट तर्कों के आधार पर, यह याद किए गए स्थानों की सूची में उपयोगिता स्थान जोड़ता है या यह सूची की सामग्री को शुद्ध करता है। जब कोई तर्क निर्दिष्ट नहीं किया जाता है, तो यह सूची की सामग्री पर रिपोर्ट करता है। -rविकल्प याद किए गए सभी स्थानों भूल जाते हैं खोल कारण बनता है।

शेल के लिए बिल्ट-इन के रूप में दी गई उपयोगिताएँ हैश द्वारा रिपोर्ट नहीं की गई हैं।

यह देखने के अलावा कि मैंने कितनी बार कमांड दर्ज की है, मैं इसकी उपयोगिता नहीं देख सकता hash

यह भी ingeekstuff.com के शीर्ष 15 उपयोगी आदेशों में चित्रित किया गया था

किन तरीकों से hashउपयोगी है?

जवाबों:


94

hashएक बैश बिल्ट-इन कमांड है। हैश टेबल की एक विशेषता है bash कि यह $PATHहर बार जब आप स्मृति में परिणाम कैशिंग द्वारा एक आदेश टाइप करने से रोकता है । तालिका उन घटनाओं पर साफ़ हो जाती है जो स्पष्ट रूप से परिणामों को अमान्य करती हैं (जैसे संशोधित करना $PATH)

hashआदेश सिर्फ आपको लगता है कि प्रणाली (जो भी कारण के लिए यदि आपको लगता है कि आप की जरूरत है) के साथ कैसे सहभागिता है।

कुछ उपयोग के मामले:

  • जैसे आपने देखा कि यह कितनी बार प्रिंट करता है, अगर आप इसे बिना किसी तर्क के टाइप करते हैं तो कौन सी कमांड आती है। यह आपको बता सकता है कि आप कौन सी आज्ञाओं का सबसे अधिक उपयोग करते हैं।

  • आप इसे गैर-मानक स्थानों में निष्पादन योग्य याद रखने के लिए भी उपयोग कर सकते हैं।

उदाहरण:

[root@policyServer ~]# hash -p /lol-wut/whoami whoami
[root@policyServer ~]# whoami
Not what you're thinking
[root@policyServer ~]# which whoami
/usr/bin/whoami
[root@policyServer ~]# /usr/bin/whoami
root
[root@policyServer ~]#

जो उपयोगी हो सकता है यदि आपके पास बस एक निर्देशिका में एक निष्पादन योग्य है जिसके बाहर $PATHआप केवल उस निर्देशिका में सब कुछ शामिल करने के बजाय नाम लिखना चाहते हैं (यदि आप इसे जोड़ते हैं तो इसका प्रभाव होगा $PATH)।

एक उपनाम आमतौर पर यह भी कर सकता है, हालांकि और जब से आप वर्तमान शेल के व्यवहार को संशोधित कर रहे हैं, यह उन कार्यक्रमों में मैप नहीं किया जाता है जिन्हें आप बंद करते हैं। अकेला निष्पादन योग्य के लिए एक सहानुभूति शायद यहाँ बेहतर विकल्प है। hashयह करने का एक तरीका है।

  • आप इसका उपयोग अन-याद रखने वाले फ़ाइल पथों के लिए कर सकते हैं। यह उपयोगी है अगर एक नया निष्पादन योग्य पहले की PATHनिर्देशिका में पॉप अप करता है या mvकहीं और जाता है और आप बैश को बाहर जाने के लिए बाध्य करना चाहते हैं और अंतिम स्थान के बजाय इसे ढूंढना याद रखते हैं।

उदाहरण:

[root@policyServer ~]# hash
hits    command
   1    /bin/ls
[root@policyServer ~]# cp /bin/ls /lol-wut
[root@policyServer ~]# hash
hits    command
   1    /bin/cp
   1    /bin/ls
[root@policyServer ~]# hash -d ls
[root@policyServer ~]# ls
default.ldif  newDIT.ldif  notes.txt  users.ldif
[root@policyServer ~]# hash
hits    command
   1    /bin/cp
   1    /lol-wut/ls
[root@policyServer ~]#

cpआदेश के एक नए संस्करण की वजह से lsनिष्पादन योग्य मेरे में पहले दिखाने के लिए $PATHलेकिन हैश तालिका की एक पर्ज ट्रिगर नहीं किया। मैं हैश तालिका से hash -dप्रविष्टि के लिए चुनिंदा रूप से शुद्ध करता था ls। बैश को फिर से देखने के लिए मजबूर किया गया था $PATHऔर जब यह किया, तो इसे नए स्थान पर पाया (पहले $ PATH में पहले की तुलना में चल रहा था)।

आप चुनिंदा रूप से इसे $PATH"व्यवहार से निष्पादन योग्य का नया स्थान ढूंढ सकते हैं, हालांकि:

[root@policyServer ~]# hash
hits    command
   1    /bin/ls
[root@policyServer ~]# hash ls
[root@policyServer ~]# hash
hits    command
   0    /lol-wut/ls
[root@policyServer ~]#

आप ज्यादातर ऐसा करना चाहते हैं यदि आप हैश टेबल से कुछ चाहते थे और 100% नहीं थे कि आप लॉगआउट कर सकते थे और फिर सफलतापूर्वक वापस आ सकते थे, या आप अपने शेल में किए गए कुछ संशोधनों को संरक्षित करना चाहते थे।

बासी मैपिंग से छुटकारा पाने के लिए, आप भी कर सकते हैं hash -r(या export PATH=$PATH) जो प्रभावी रूप से बस बैश की पूरी हैश टेबल को शुद्ध करता है।

इस तरह की बहुत कम स्थितियाँ हैं। मुझे नहीं पता कि मैं इसे "सबसे उपयोगी" कमांडों में से एक कहूंगा लेकिन इसके कुछ उपयोग मामले हैं।


मुझे आश्चर्य है कि 'हैश' नाम कहां से आया है। उदाहरण के लिए "कैश" के बारे में क्या है? :)।
माइकल

2
@ मिचेल क्योंकि hashकमांड आंतरिक रूप से मैपिंग को स्टोर करने के लिए हैश टेबल का उपयोग करता है। en.wikipedia.org/wiki/Hash_table
jlliagre

10
यह ध्यान दिया जाना चाहिए कि विशिष्ट hashनहीं है bash, कमांड की उत्पत्ति बॉर्न शेल में SVR2 में हुई थी (हालांकि कमांड के हैशिंग पथ की विशेषता cshइससे पहले आती है) और सभी बॉर्न-जैसे और पॉसिक्स शेल में पाया जाता है।
स्टीफन चेजलस 21

1
export PATH=$PATHमेज को साफ करने के बजाय , hash -rपर्याप्त होना चाहिए।
रेवरॉन

1
एक अन्य उपयोग का मामला है जब एक प्रोग्राम की दूसरी कॉपी को आपके $ PATH के पहले भाग में स्थापित करना। आपको hash -rपुराने संस्करण की आवश्यकता होगी या नहीं क्योंकि $ PATH नहीं बदला और इसलिए Bash को यह महसूस नहीं होता है कि वह उसी प्रोग्राम को पहले (उच्च प्राथमिकता) निर्देशिका से लोड कर सकता है। देखें conda.pydata.org/docs/... जानकारी के लिए।
जॉन Zwinck

37

यहाँ क्लासिक उपयोग है, सरलीकृत:

# My PATH contains /home/rici/bin as well as the Usual Suspects:
# (the real one has lots more)
$ echo $PATH
/home/rici/bin:/usr/local/bin:/usr/bin:/bin

# I've installed a program called hello in /usr/local/bin
$ $ cat /usr/local/bin/hello
#!/bin/bash

echo Hello, world. I live at $0

# The program works.
$ hello
Hello, world. I live at /usr/local/bin/hello

# Now I want to create a better hello, just for me. I put it in
# my own bin directory, and according to my PATH, it should come first.
$ cp /usr/local/bin/hello ~/bin/hello

# So now I will try running it
$ hello
Hello, world. I live at /usr/local/bin/hello

# WTF? Oh, forgot to run hash.
# Tell bash to update where to look for hello
$ hash hello
$ hello
Hello, world. I live at /home/rici/bin/hello

# Ah, all is well.

जैसा कि यहाँ नोट किया गया हैश तालिका के चयनात्मक अद्यतन एक ही आदेश के साथ मंगाया जा सकता है hash hello
Ioannis Filippidis

@ जोंटेक्स: ठीक है, बदल गया।
रिसी

हैश टेबल मौजूद है यह जानने से पहले अजीब कीड़े की क्षमता की कल्पना करो! क्या उन परिस्थितियों की एक सूची है जब हैश तालिका स्वचालित रूप से ताज़ा हो जाती है?
बेंजामिन

@बेनजी: यह कभी भी अपने आप ताज़ा नहीं होता (एक पूरे के रूप में)। यदि आप पॉज़िक्स मोड में बैश चलाते हैं या setopt -s checkhashकमांड के लिए हैशेड निष्पादन योग्य नहीं रहता है, तो उस कमांड के लिए हैश प्रविष्टि को अपडेट किया जाएगा। लेकिन ध्यान दें कि हर बैश सत्र की अपनी एक हैश तालिका होती है, इसलिए सत्र को बंद करना और एक नया शुरू करना प्रभावी रूप से हैश को खाली करता है। ( hash -rऐसा करने का एक आसान तरीका है।)
रीसी

अपडेट करना $PATH, या एक नया बैश टर्मिनल लॉन्च करना , दोनों टेबल को साफ करने के लिए दिखाई देते हैं।
बेंजामिन

17

यहाँ एक उपयोगी उपयोग है hash:

hash php 2> /dev/null || hash -p /usr/local/foobar/php/bin/php php 2> /dev/null

इसका मतलब है: अगर php पथ में नहीं है, तो उपयोग करें

/usr/local/foobar/php/bin/

7

हाँ, बैश संदर्भ मैनुअल कहता है:

$ PATH में निर्देशिकाओं की पूरी खोज केवल तभी की जाती है जब कमांड हैश तालिका में नहीं मिली हो।

लेकिन आप हैशिंग को अक्षम कर सकते हैं set +h:

-h - लोकेट करें और याद रखें (हैश) कमांड्स क्योंकि उन्हें निष्पादन के लिए देखा जाता है। यह विकल्प डिफॉल्ट द्वारा सक्षम हो जाता है।

प्रयत्न, कोशिश:

set +h
hash # prints bash: hash: hashing disabled
echo $? # prints 1

उसी के लिए है hash -r, hash NAMEआदि

एक "कमांड डिटेक्शन" ( इस या उस तरह ) काम नहीं करता है:

set -h
hash ls >/dev/null 2>&1 || echo "Please install ls" >&2 # prints nothing

set +h
hash ls >/dev/null 2>&1 || echo "Please install ls" >&2 # prints Please install ls

आप कुछ इस तरह लिख सकते हैं:

old_options="$-"
set -h
hash ls >/dev/null 2>&1 || echo "Please install ls" >&2
[[ "$old_options" =~ "h" ]] || set +h

या (@mikeserv के लिए धन्यवाद) किसी भी नए चर असाइन करने के लिए या कोई परीक्षण किए बिना:

set -h -- "-${-:--}" "$@"
hash ls >/dev/null 2>&1 || echo "Please install ls" >&2
set +h "$@"

1
आपकी old_optionsबात के लिए - मैं आमतौर पर ऐसा कुछ करता हूं: set -h -- "-${-:--}" "$@"; hash ...; set +h "$@"इसलिए यह सब बिना किसी नए चर को असाइन किए या किसी भी परीक्षण या जो कुछ भी किए बिना स्वचालित रूप से जगह में गिर जाता है।
मिकसर्व

5

एक आदेश उपलब्ध है या नहीं, इसका आसान पता लगाना:

CMD=gzip
if hash bzip2; then
    CMD=$_
fi
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.