बैश स्क्रिप्ट में वर्तमान निर्देशिका नाम (पूर्ण पथ के बिना) प्राप्त करें


818

मुझे बस वर्तमान कार्यशील निर्देशिका का नाम बैश स्क्रिप्ट में कैसे मिलेगा, या इससे भी बेहतर, बस एक टर्मिनल कमांड।

pwdवर्तमान कार्यशील निर्देशिका का पूर्ण पथ देता है, उदाहरण के लिए, /opt/local/binलेकिन मैं केवल चाहता हूंbin


जवाबों:


1114

बेसन की कोई आवश्यकता नहीं है, और विशेष रूप से सब-रनिंग पीडीडब्ल्यू के लिए कोई ज़रूरत नहीं है (जो अतिरिक्त, और महंगी, कांटा संचालन जोड़ता है ); शेल आंतरिक रूप से पैरामीटर विस्तार का उपयोग कर सकता है :

result=${PWD##*/}          # to assign to a variable

printf '%s\n' "${PWD##*/}" # to print to stdout
                           # ...more robust than echo for unusual names
                           #    (consider a directory named -e or -n)

printf '%q\n' "${PWD##*/}" # to print to stdout, quoted for use as shell input
                           # ...useful to make hidden characters readable.

ध्यान दें कि यदि आप इस तकनीक को अन्य परिस्थितियों में लागू कर रहे हैं (नहीं PWD, लेकिन निर्देशिका नाम रखने वाले कुछ अन्य चर), तो आपको किसी भी ट्रैड स्लैश को ट्रिम करने की आवश्यकता हो सकती है। नीचे कई ट्रेलिंग स्लैश के साथ भी काम करने के लिए बैश के एक्सग्लोब सपोर्ट का उपयोग किया गया है :

dirname=/path/to/somewhere//
shopt -s extglob           # enable +(...) glob syntax
result=${dirname%%+(/)}    # trim however many trailing slashes exist
result=${result##*/}       # remove everything before the last / that still remains
printf '%s\n' "$result"

वैकल्पिक रूप से, बिना extglob:

dirname="/path/to/somewhere//"
result="${dirname%"${dirname##*[!/]}"}" # extglob-free multi-trailing-/ trim
result="${result##*/}"                  # remove everything before the last /

31
$ {PWD ## * /} और $ PWD में क्या अंतर है?
Mr_Chimp

24
@Mr_Chimp पूर्व एक पैरामीटर विस्तार ऑपरेशन है जो केवल बेसन प्रदान करने के लिए बाकी निर्देशिका को चलाता है। मेरे पास पैरामीटर विस्तार पर प्रलेखन के जवाब में एक लिंक है; यदि आपके कोई प्रश्न हैं, तो उसका अनुसरण करने में संकोच न करें।
चार्ल्स डफी

24
@stefgosselin $PWDएक बिल्ट-इन बैश वैरिएबल का नाम है; सभी अंतर्निहित वैरिएबल नाम ऑल-कैप्स में हैं (स्थानीय चर से उन्हें अलग करने के लिए, जिसमें हमेशा कम से कम एक कम-वर्ण चरित्र होना चाहिए)। result=${PWD#*/}का मूल्यांकन नहीं करता है /full/path/to/directory; इसके बजाय, यह केवल पहला तत्व स्ट्रिप्स बनाता है, जिससे यह बन जाता है path/to/directory; दो #वर्णों का उपयोग करने से पैटर्न मैच लालची हो जाता है, जितने संभव हो उतने वर्णों से मेल खाते हैं। अधिक के लिए, उत्तर में लिंक पैरामीटर विस्तार पृष्ठ पढ़ें।
चार्ल्स डफी

5
ध्यान दें कि प्रतीकात्मक लिंक के माध्यम से आईएनजी से उत्पन्न होने वाली जटिलताओं के कारण, आउटपुट से pwdहमेशा समान नहीं होता है , चाहे बैश का विकल्प सेट हो, और इसी तरह। यह विशेष रूप से स्वचालित निर्देशिकाओं के संचालन के आसपास बुरा हो जाता था, जहां तार्किक के बजाय भौतिक पथ को रिकॉर्ड करने से एक पथ का उत्पादन होता था, जिसका यदि उपयोग किया जाता है, तो स्वचालित रूप से एक निर्देशिका का उपयोग करने वाले को स्वतःस्फूर्त रूप से अनुमति देगा। $PWDcd-o physical
एलेक्स नॉर्थ-कीज

3
अच्छा! किसी को मेरे जैसे पुराने बोर्न शेल लोगों के लिए एक किताब लिखनी चाहिए। शायद वहाँ एक बाहर है? यह एक crotchity वर्ष sys तरह सामान कह व्यवस्थापक, "मेरे दिन में वापस हम केवल हो सकता था shऔर cshऔर यदि आप आप पूरे पढ़ने के लिए किया था काम करने के लिए backspace कुंजी चाहते थे sttyआदमी पेज, और हम यह पसंद आया!"
रेड क्रिकेट

333

basenameप्रोग्राम का उपयोग करें । आपके मामले के लिए:

% basename "$PWD"
bin

19
क्या यह basenameकार्यक्रम का उद्देश्य नहीं है ? उद्धरण गुम होने के अलावा इस उत्तर में क्या गलत है?
नाच -

11
@ नाच basenameवास्तव में एक बाहरी प्रोग्राम है जो सही काम करता है, लेकिन किसी भी चीज़ के लिए कोई भी बाहरी प्रोग्राम चलाने पर बैश केवल आउट-ऑफ-द-बॉक्स का उपयोग करके किया जा सकता है, यह केवल अंतर्निहित कार्यक्षमता है, प्रदर्शन प्रभाव को प्रभावित करता है ( fork(),execve() , wait(), आदि) के लिए कोई कारण नहीं।
चार्ल्स डफी

3
... एक अलग रूप में, करने के लिए अपने आपत्तियों के रूप में basenameयहाँ नहीं है लागू करने के लिए dirname, क्योंकि dirnameकार्यक्षमता है ${PWD##*/}नहीं करता है - करने के लिए कोई स्लैश के साथ एक स्ट्रिंग बदलने .उदाहरण के लिए,। इस प्रकार, dirnameबाहरी उपकरण के रूप में उपयोग करने पर प्रदर्शन ओवरहेड होता है, इसकी कार्यक्षमता भी होती है जो उसी की भरपाई करने में मदद करती है।
चार्ल्स डफी

4
@LouisMaddox, kibitzing का एक बिट: functionकीवर्ड मानकीकृत सिंटैक्स पर कोई मान जोड़े बिना POSIX- असंगत है, और उद्धरणों की कमी रिक्त स्थान के साथ निर्देशिका नामों में बग पैदा करेगी। wdexec() { "./$(basename "$PWD")"; }एक बेहतर विकल्प हो सकता है।
चार्ल्स डफी

27
निश्चित रूप से basename"कुशल" का उपयोग कम है। लेकिन यह शायद डेवलपर उत्पादकता के संदर्भ में अधिक कुशल है क्योंकि बदसूरत बैश सिंटैक्स की तुलना में इसे याद रखना आसान है। तो अगर आपको यह याद है, तो इसके लिए जाएं। अन्यथा, basenameबस के रूप में अच्छी तरह से काम करता है। क्या किसी को कभी भी बैश स्क्रिप्ट के "प्रदर्शन" में सुधार करना और इसे अधिक कुशल बनाना है?
usr

139
$ echo "${PWD##*/}"

​​​​​


2
@ जोकैप ... सिवाय इसके कि वहां प्रतिध्वनि का उपयोग, तर्क को उद्धृत किए बिना, गलत है । यदि निर्देशिका नाम में कई स्थान हैं, या एक टैब वर्ण है, तो यह एक ही स्थान पर ढह जाएगा; यदि इसमें वाइल्डकार्ड वर्ण है, तो इसका विस्तार किया जाएगा। सही उपयोग होगा echo "${PWD##*/}"
चार्ल्स डफी

9
@ जोकैप ... भी, मुझे यकीन नहीं है कि "इको" वास्तव में उत्तर का एक वैध हिस्सा है। प्रश्न यह था कि उत्तर कैसे प्राप्त किया जाए , उत्तर को कैसे प्रिंट किया जाए; यदि लक्ष्य को एक चर के लिए असाइन करना था, उदाहरण के लिए, name=${PWD##*/}सही होगा, और name=$(echo "${PWD##*/}")गलत होगा (एक अनावश्यक-अक्षमता की भावना में)।
चार्ल्स डफी

24

आप pwd और बेसन के संयोजन का उपयोग कर सकते हैं। उदाहरण के लिए

#!/bin/bash

CURRENT=`pwd`
BASENAME=`basename "$CURRENT"`

echo "$BASENAME"

exit;

18
कृपया नहीं। बैकटिक्स एक उप-संस्करण बनाते हैं (इस प्रकार, एक कांटा संचालन) - और इस मामले में, आप उन्हें दो बार उपयोग कर रहे हैं ! [एक अतिरिक्त, यद्यपि शैलीगत वक्रोक्ति - चर नाम कम-मामले में होना चाहिए जब तक कि आप उन्हें पर्यावरण को निर्यात नहीं कर रहे हैं या वे एक विशेष, आरक्षित मामला है]।
चार्ल्स डफी

11
और दूसरी शैली के वक्रोक्ति बैकटिक्स को $ () द्वारा प्रतिस्थापित किया जाना चाहिए। अभी भी कांटे हैं, लेकिन अधिक पठनीय और कम excaping के साथ की जरूरत है।
जेरेमी वॉल

1
कन्वेंशन द्वारा, पर्यावरण चर (PATH, EDITOR, SHELL, ...) और आंतरिक शेल चर (BASH_VERSION, RANDOM, ...) पूरी तरह से पूंजीकृत हैं। अन्य सभी चर नाम लोअरकेस में होने चाहिए। चूँकि चर नाम केस-संवेदी होते हैं, यह कन्वेंशन गलती से पर्यावरण और आंतरिक चर को ओवरराइड करने से बचता है।
रानी अलबेग वेन

2
अधिवेशन पर निर्भर करता है। एक तर्क दे सकता है कि सभी शेल चर पर्यावरण चर (शेल के आधार पर) हैं, और इस प्रकार सभी शेल चर सभी-कैप में होने चाहिए। कोई और गुंजाइश के आधार पर बहस कर सकता है - वैश्विक चर ऑल-कैप हैं, जबकि स्थानीय चर लोअरकेस हैं, और ये सभी वैरिएबल हैं। फिर भी एक और तर्क हो सकता है कि चर-उपपाठ बनाने से कमांडों के लिपटे शेल स्क्रिप्ट के साथ एक अतिरिक्त परत जुड़ जाती है, जो सभी लोअर-केस शॉर्ट लेकिन सार्थक शब्द भी हैं। मैं उन तर्कों में से किसी के साथ भी सहमत / सहमत हो सकता हूं / नहीं, लेकिन मैंने तीनों को उपयोग में देखा है। :)
dannysauer 21

17

कैसे grep के बारे में:

pwd | grep -o '[^/]*$'

अनुशंसा नहीं करेंगे क्योंकि यह कुछ रंग जानकारी प्राप्त करने के लिए लगता है, जबकि pwd | xargs basenameनहीं है .. शायद यह महत्वपूर्ण नहीं है, लेकिन अन्य उत्तर सरल और पूरे वातावरण में अधिक सुसंगत है
davidhq

8

मुझे चयनित उत्तर (चार्ल्स डफी) पसंद है, लेकिन सावधान रहें यदि आप एक सिमिलर डायर में हैं और आप लक्ष्य डायर का नाम चाहते हैं। दुर्भाग्य से मुझे नहीं लगता कि यह एक एकल पैरामीटर विस्तार अभिव्यक्ति में किया जा सकता है, शायद मैं गलत हूं। यह काम करना चाहिए:

target_PWD=$(readlink -f .)
echo ${target_PWD##*/}

इसे देखने के लिए, एक प्रयोग:

cd foo
ln -s . bar
echo ${PWD##*/}

रिपोर्ट "बार"

DIRNAME

पथ के प्रमुख निर्देशिकाओं को दिखाने के लिए (बिना फोर्क-एक्ज़ीक्यूटेशन के / usr / bin / dirname):

echo ${target_PWD%/*}

यह जैसे foo / bar / baz -> foo / bar को रूपांतरित करेगा


5
दुर्भाग्य से, readlink -fएक GNU एक्सटेंशन है, और इस तरह BSDs (OS X सहित) पर उपलब्ध नहीं है।
Xiong Chiamiov

8
echo "$PWD" | sed 's!.*/!!'

यदि आप बॉर्न शेल का उपयोग कर रहे हैं या ${PWD##*/}उपलब्ध नहीं है।


4
FYI करें, ${PWD##*/}POSIX श - प्रत्येक आधुनिक / बिन / श (डैश, राख, आदि सहित) इसका समर्थन करता है; हाल ही के बॉक्स पर वास्तविक बॉर्न हिट करने के लिए, आपको हल्के पुराने सोलारिस सिस्टम पर होना चाहिए। उससे परे - echo "$PWD"; उद्धरणों को छोड़ने से कीड़े हो जाते हैं (यदि निर्देशिका नाम में स्थान, वाइल्डकार्ड वर्ण, आदि हैं)।
चार्ल्स डफी

1
हां, मैं पुराने सोलारिस सिस्टम का इस्तेमाल कर रहा था। मैंने उद्धरणों का उपयोग करने के लिए कमांड को अपडेट किया है।
अनोमल

7

यह धागा महान है! यहाँ एक और स्वाद है:

pwd | awk -F / '{print $NF}'

5

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

i="$IFS";IFS='/';set -f;p=($PWD);set +f;IFS="$i";echo "${p[-1]}"

एक के रूप में अतिरिक्त बोनस आप आसानी के साथ मूल निर्देशिका का नाम प्राप्त कर सकते हैं:

[ "${#p[@]}" -gt 1 ] && echo "${p[-2]}"

ये बैश 4.3-अल्फा या नए पर काम करेंगे।


आश्चर्यजनक रूप से? सिर्फ मजाक कर रहे हैं, लेकिन दूसरों को याद करने के लिए बहुत कम और आसान है
कोडवर्ड

यह काफ़ी मज़ेदार है = P ने इससे पहले $ IFS (आंतरिक क्षेत्र विभाजक) के बारे में नहीं सुना था। मेरा बैश बहुत पुराना था, लेकिन इसे यहाँ परीक्षण कर सकते हैं: jdoodle.com/test-bash-shell-script-online
Stan Kurdziel

5

उपयोग:

basename "$PWD"

या

IFS=/ 
var=($PWD)
echo ${var[-1]} 

आंतरिक फ़ाइल नाम विभाजक (IFS) को वापस अंतरिक्ष में बदलें।

IFS= 

IFS के बाद एक स्थान है।


4
basename $(pwd)

या

echo "$(basename $(pwd))"

2
सही होने के लिए अधिक उद्धरणों की आवश्यकता है - जैसा कि यह है, pwdपास होने से पहले स्ट्रिंग-विभाजन और ग्लोब-विस्तारित का उत्पादन होता है basename
चार्ल्स डफी

इस प्रकार, basename "$(pwd)"- हालांकि यह सिर्फ की तुलना में बहुत ही अक्षम है basename "$PWD", जो कि कॉलिंग के बजाय पैरामीटर विस्तार का उपयोग करने की तुलना में स्वयं अक्षम है basename
चार्ल्स डफी

4

मेरी तरह वहाँ जॉकी खोजने के लिए:

find $PWD -maxdepth 0 -printf "%f\n"

असामान्य निर्देशिका नामों को सही ढंग से संभालने के $PWDलिए बदलें "$PWD"
चार्ल्स डफी

3

मैं आमतौर पर श स्क्रिप्ट में इसका इस्तेमाल करता हूं

SCRIPTSRC=`readlink -f "$0" || echo "$0"`
RUN_PATH=`dirname "${SCRIPTSRC}" || echo .`
echo "Running from ${RUN_PATH}"
...
cd ${RUN_PATH}/subfolder

आप इसका उपयोग चीजों को स्वचालित करने के लिए कर सकते हैं ...


readlink: illegal option -- f usage: readlink [-n] [file ...]


1

महज प्रयोग करें:

pwd | xargs basename

या

basename "`pwd`"

2
यह सभी मामलों में इस सवाल का जवाब पहले से Arkady (द्वारा दिए गए एक बुरा संस्करण है stackoverflow.com/a/1371267/14122 ): xargsformultion अक्षम और त्रुटिपूर्ण है जब निर्देशिका नाम शाब्दिक नई पंक्तियों या उद्धरण वर्ण, और दूसरा सूत्रीकरण कॉल pwdआदेश एक अंतर्निहित चर विस्तार के माध्यम से एक ही परिणाम को प्राप्त करने के बजाय, एक उपधारा में।
चार्ल्स डफी

@CharlesDuffy फिर भी यह सवाल का एक वैध और व्यावहारिक जवाब है।
बैचफ

1

यदि आप bash प्रॉम्प्ट क्षेत्र में केवल वर्तमान निर्देशिका देखना चाहते हैं, तो आप .bashrcफ़ाइल को संपादित कर सकते हैं ~। बदले \wके लिए \Wलाइन में:

PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '

भागो source ~/.bashrcऔर यह केवल प्रॉम्प्ट क्षेत्र में निर्देशिका नाम प्रदर्शित करेगा।

रेफरी: /superuser/60555/show-only-current-directory-name-not-full-path-on-bash-prompt


0

आप बेसन उपयोगिता का उपयोग कर सकते हैं जो स्ट्रिंग से / और प्रत्यय (यदि स्ट्रिंग में मौजूद है) में समाप्त होने वाले किसी भी उपसर्ग को हटाता है, और मानक आउटपुट पर परिणाम प्रिंट करता है।

$basename <path-of-directory>

0

मैं दृढ़ता से उपयोग करना पसंद करता हूं gbasename, जो कि जीएनयू कोर्यूटिल्स का हिस्सा है।


FYI करें, यह मेरे Ubuntu वितरण के साथ नहीं आता है।
३४ पर कटास्टिक यात्रा

@KatasticVoyage, यह उबंटू में है, इसे basenameवहां बुलाया जाता है। यह आमतौर gbasenameपर केवल MacOS और अन्य प्लेटफार्मों पर बुलाया जाता है जो अन्यथा गैर-जीएनयू बेसनेम के साथ जहाज करते हैं।
चार्ल्स डफी

-1

निम्न आदेशों के परिणामस्वरूप आपकी वर्तमान कार्यशील निर्देशिका को एक bash स्क्रिप्ट में मुद्रित किया जाएगा।

pushd .
CURRENT_DIR="`cd $1; pwd`"
popd
echo $CURRENT_DIR

2
(1) मुझे यकीन नहीं है कि हम यह सुनिश्चित कर रहे हैं कि तर्क सूची ऐसी है $1जिसमें वर्तमान कार्यशील निर्देशिका शामिल होगी। (२) यहाँ कोई उद्देश्य नहीं है pushdऔर popdक्योंकि बैकटिक्स के अंदर कुछ भी सब-सब्स्क्राइब नहीं किया गया है - इसलिए यह आरंभ करने के लिए मूल शेल की निर्देशिका को प्रभावित नहीं कर सकता है। (3) "$(cd "$1"; pwd)"व्हॉट्सएप के साथ निर्देशिका नामों के खिलाफ उपयोग करना अधिक पठनीय और लचीला दोनों होगा।
चार्ल्स डफी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.