मुझे बस वर्तमान कार्यशील निर्देशिका का नाम बैश स्क्रिप्ट में कैसे मिलेगा, या इससे भी बेहतर, बस एक टर्मिनल कमांड।
pwd
वर्तमान कार्यशील निर्देशिका का पूर्ण पथ देता है, उदाहरण के लिए, /opt/local/bin
लेकिन मैं केवल चाहता हूंbin
मुझे बस वर्तमान कार्यशील निर्देशिका का नाम बैश स्क्रिप्ट में कैसे मिलेगा, या इससे भी बेहतर, बस एक टर्मिनल कमांड।
pwd
वर्तमान कार्यशील निर्देशिका का पूर्ण पथ देता है, उदाहरण के लिए, /opt/local/bin
लेकिन मैं केवल चाहता हूंbin
जवाबों:
बेसन की कोई आवश्यकता नहीं है, और विशेष रूप से सब-रनिंग पीडीडब्ल्यू के लिए कोई ज़रूरत नहीं है (जो अतिरिक्त, और महंगी, कांटा संचालन जोड़ता है ); शेल आंतरिक रूप से पैरामीटर विस्तार का उपयोग कर सकता है :
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 /
$PWD
एक बिल्ट-इन बैश वैरिएबल का नाम है; सभी अंतर्निहित वैरिएबल नाम ऑल-कैप्स में हैं (स्थानीय चर से उन्हें अलग करने के लिए, जिसमें हमेशा कम से कम एक कम-वर्ण चरित्र होना चाहिए)। result=${PWD#*/}
का मूल्यांकन नहीं करता है /full/path/to/directory
; इसके बजाय, यह केवल पहला तत्व स्ट्रिप्स बनाता है, जिससे यह बन जाता है path/to/directory
; दो #
वर्णों का उपयोग करने से पैटर्न मैच लालची हो जाता है, जितने संभव हो उतने वर्णों से मेल खाते हैं। अधिक के लिए, उत्तर में लिंक पैरामीटर विस्तार पृष्ठ पढ़ें।
pwd
हमेशा समान नहीं होता है , चाहे बैश का विकल्प सेट हो, और इसी तरह। यह विशेष रूप से स्वचालित निर्देशिकाओं के संचालन के आसपास बुरा हो जाता था, जहां तार्किक के बजाय भौतिक पथ को रिकॉर्ड करने से एक पथ का उत्पादन होता था, जिसका यदि उपयोग किया जाता है, तो स्वचालित रूप से एक निर्देशिका का उपयोग करने वाले को स्वतःस्फूर्त रूप से अनुमति देगा। $PWD
cd
-o physical
sh
और csh
और यदि आप आप पूरे पढ़ने के लिए किया था काम करने के लिए backspace कुंजी चाहते थे stty
आदमी पेज, और हम यह पसंद आया!"
basename
प्रोग्राम का उपयोग करें । आपके मामले के लिए:
% basename "$PWD"
bin
basename
कार्यक्रम का उद्देश्य नहीं है ? उद्धरण गुम होने के अलावा इस उत्तर में क्या गलत है?
basename
वास्तव में एक बाहरी प्रोग्राम है जो सही काम करता है, लेकिन किसी भी चीज़ के लिए कोई भी बाहरी प्रोग्राम चलाने पर बैश केवल आउट-ऑफ-द-बॉक्स का उपयोग करके किया जा सकता है, यह केवल अंतर्निहित कार्यक्षमता है, प्रदर्शन प्रभाव को प्रभावित करता है ( fork()
,execve()
, wait()
, आदि) के लिए कोई कारण नहीं।
basename
यहाँ नहीं है लागू करने के लिए dirname
, क्योंकि dirname
कार्यक्षमता है ${PWD##*/}
नहीं करता है - करने के लिए कोई स्लैश के साथ एक स्ट्रिंग बदलने .
उदाहरण के लिए,। इस प्रकार, dirname
बाहरी उपकरण के रूप में उपयोग करने पर प्रदर्शन ओवरहेड होता है, इसकी कार्यक्षमता भी होती है जो उसी की भरपाई करने में मदद करती है।
function
कीवर्ड मानकीकृत सिंटैक्स पर कोई मान जोड़े बिना POSIX- असंगत है, और उद्धरणों की कमी रिक्त स्थान के साथ निर्देशिका नामों में बग पैदा करेगी। wdexec() { "./$(basename "$PWD")"; }
एक बेहतर विकल्प हो सकता है।
basename
"कुशल" का उपयोग कम है। लेकिन यह शायद डेवलपर उत्पादकता के संदर्भ में अधिक कुशल है क्योंकि बदसूरत बैश सिंटैक्स की तुलना में इसे याद रखना आसान है। तो अगर आपको यह याद है, तो इसके लिए जाएं। अन्यथा, basename
बस के रूप में अच्छी तरह से काम करता है। क्या किसी को कभी भी बैश स्क्रिप्ट के "प्रदर्शन" में सुधार करना और इसे अधिक कुशल बनाना है?
$ echo "${PWD##*/}"
echo "${PWD##*/}"
।
name=${PWD##*/}
सही होगा, और name=$(echo "${PWD##*/}")
गलत होगा (एक अनावश्यक-अक्षमता की भावना में)।
आप pwd और बेसन के संयोजन का उपयोग कर सकते हैं। उदाहरण के लिए
#!/bin/bash
CURRENT=`pwd`
BASENAME=`basename "$CURRENT"`
echo "$BASENAME"
exit;
मुझे चयनित उत्तर (चार्ल्स डफी) पसंद है, लेकिन सावधान रहें यदि आप एक सिमिलर डायर में हैं और आप लक्ष्य डायर का नाम चाहते हैं। दुर्भाग्य से मुझे नहीं लगता कि यह एक एकल पैरामीटर विस्तार अभिव्यक्ति में किया जा सकता है, शायद मैं गलत हूं। यह काम करना चाहिए:
target_PWD=$(readlink -f .)
echo ${target_PWD##*/}
इसे देखने के लिए, एक प्रयोग:
cd foo
ln -s . bar
echo ${PWD##*/}
रिपोर्ट "बार"
पथ के प्रमुख निर्देशिकाओं को दिखाने के लिए (बिना फोर्क-एक्ज़ीक्यूटेशन के / usr / bin / dirname):
echo ${target_PWD%/*}
यह जैसे foo / bar / baz -> foo / bar को रूपांतरित करेगा
readlink -f
एक GNU एक्सटेंशन है, और इस तरह BSDs (OS X सहित) पर उपलब्ध नहीं है।
echo "$PWD" | sed 's!.*/!!'
यदि आप बॉर्न शेल का उपयोग कर रहे हैं या ${PWD##*/}
उपलब्ध नहीं है।
${PWD##*/}
POSIX श - प्रत्येक आधुनिक / बिन / श (डैश, राख, आदि सहित) इसका समर्थन करता है; हाल ही के बॉक्स पर वास्तविक बॉर्न हिट करने के लिए, आपको हल्के पुराने सोलारिस सिस्टम पर होना चाहिए। उससे परे - echo "$PWD"
; उद्धरणों को छोड़ने से कीड़े हो जाते हैं (यदि निर्देशिका नाम में स्थान, वाइल्डकार्ड वर्ण, आदि हैं)।
हैरानी की बात है, किसी ने इस विकल्प का उल्लेख नहीं किया है जो केवल बिल-इन कमांड का उपयोग करता है:
i="$IFS";IFS='/';set -f;p=($PWD);set +f;IFS="$i";echo "${p[-1]}"
एक के रूप में अतिरिक्त बोनस आप आसानी के साथ मूल निर्देशिका का नाम प्राप्त कर सकते हैं:
[ "${#p[@]}" -gt 1 ] && echo "${p[-2]}"
ये बैश 4.3-अल्फा या नए पर काम करेंगे।
उपयोग:
basename "$PWD"
या
IFS=/
var=($PWD)
echo ${var[-1]}
आंतरिक फ़ाइल नाम विभाजक (IFS) को वापस अंतरिक्ष में बदलें।
IFS=
IFS के बाद एक स्थान है।
basename $(pwd)
या
echo "$(basename $(pwd))"
pwd
पास होने से पहले स्ट्रिंग-विभाजन और ग्लोब-विस्तारित का उत्पादन होता है basename
।
basename "$(pwd)"
- हालांकि यह सिर्फ की तुलना में बहुत ही अक्षम है basename "$PWD"
, जो कि कॉलिंग के बजाय पैरामीटर विस्तार का उपयोग करने की तुलना में स्वयं अक्षम है basename
।
मेरी तरह वहाँ जॉकी खोजने के लिए:
find $PWD -maxdepth 0 -printf "%f\n"
$PWD
लिए बदलें "$PWD"
।
मैं आमतौर पर श स्क्रिप्ट में इसका इस्तेमाल करता हूं
SCRIPTSRC=`readlink -f "$0" || echo "$0"`
RUN_PATH=`dirname "${SCRIPTSRC}" || echo .`
echo "Running from ${RUN_PATH}"
...
cd ${RUN_PATH}/subfolder
आप इसका उपयोग चीजों को स्वचालित करने के लिए कर सकते हैं ...
रेगेक्स के साथ नीचे grep भी काम कर रहा है,
>pwd | grep -o "\w*-*$"
महज प्रयोग करें:
pwd | xargs basename
या
basename "`pwd`"
xargs
formultion अक्षम और त्रुटिपूर्ण है जब निर्देशिका नाम शाब्दिक नई पंक्तियों या उद्धरण वर्ण, और दूसरा सूत्रीकरण कॉल pwd
आदेश एक अंतर्निहित चर विस्तार के माध्यम से एक ही परिणाम को प्राप्त करने के बजाय, एक उपधारा में।
यदि आप 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
मैं दृढ़ता से उपयोग करना पसंद करता हूं gbasename
, जो कि जीएनयू कोर्यूटिल्स का हिस्सा है।
basename
वहां बुलाया जाता है। यह आमतौर gbasename
पर केवल MacOS और अन्य प्लेटफार्मों पर बुलाया जाता है जो अन्यथा गैर-जीएनयू बेसनेम के साथ जहाज करते हैं।
निम्न आदेशों के परिणामस्वरूप आपकी वर्तमान कार्यशील निर्देशिका को एक bash स्क्रिप्ट में मुद्रित किया जाएगा।
pushd .
CURRENT_DIR="`cd $1; pwd`"
popd
echo $CURRENT_DIR
$1
जिसमें वर्तमान कार्यशील निर्देशिका शामिल होगी। (२) यहाँ कोई उद्देश्य नहीं है pushd
और popd
क्योंकि बैकटिक्स के अंदर कुछ भी सब-सब्स्क्राइब नहीं किया गया है - इसलिए यह आरंभ करने के लिए मूल शेल की निर्देशिका को प्रभावित नहीं कर सकता है। (3) "$(cd "$1"; pwd)"
व्हॉट्सएप के साथ निर्देशिका नामों के खिलाफ उपयोग करना अधिक पठनीय और लचीला दोनों होगा।