पीएटीएच से एक निर्देशिका को हटाना


28

मैं मिंगडब्ल्यू का उपयोग करके wxWidgets को संकलित करने की कोशिश कर रहा हूं, और मेरे पास मेरे रास्ते में साइबरविन है, जो संघर्ष के लिए लगता है। इसलिए मैं /d/Programme/cygwin/binपाथ चर से हटाना चाहूंगा और मुझे आश्चर्य होगा कि ऐसा करने का कोई सुंदर तरीका है।

भोली दृष्टिकोण इसे एक फ़ाइल में गूंजने के लिए होगा, इसे मैन्युअल रूप से हटा दें और इसे स्रोत करें, लेकिन मुझे यकीन है कि इसके लिए बेहतर दृष्टिकोण है।


2
: कई तकनीकों को यहाँ सूचीबद्ध हैं stackoverflow.com/questions/370047/...
SLM

जवाबों:


23

$ PATH का मान "संपादित करने" के लिए कोई मानक उपकरण नहीं हैं (यानी "केवल तभी फ़ोल्डर जोड़ें जब यह पहले से मौजूद न हो" या "इस फ़ोल्डर को हटा दें")। आप बस अमल करें:

export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

यह वर्तमान सत्र के लिए होगा, यदि आप इसे स्थायी रूप से किसी भी .bashrc, bash.bashrc, / etc / प्रोफाइल में जोड़ना चाहते हैं - जो भी आपके सिस्टम और उपयोगकर्ता की आवश्यकताओं को पूरा करता है। हालाँकि, यदि आप BASH का उपयोग कर रहे हैं, तो आप निम्न कार्य भी कर सकते हैं, तो /home/wrong/dir/मान लें, आप अपने PATH चर से निर्देशिका को हटाना चाहते हैं , यह मानकर कि:

PATH=$(echo "$PATH" | sed -e 's/:\/home\/wrong\/dir$//')

तो आपके मामले में आप उपयोग कर सकते हैं

PATH=$(echo "$PATH" | sed -e 's/:\/d\/Programme\/cygwin\/bin$//')

1
यदि प्रश्न में पथ पथ चर की शुरुआत में है, तो आपको अंत में बृहदान्त्र से मेल खाना चाहिए। यह एक कष्टप्रद गुहा है जो PATH चर के आसान जेनेरिक जोड़तोड़ को जटिल करता है।
ग्रीम

4
जब इतने सारे स्लैश के साथ काम कर रहा हूं, तो मैं रेग्जिम डेलिमर /को कुछ इस तरह से बदलना पसंद करता हूं |: PATH=$(echo "$PATH" | sed -e 's|:/d/Programme/cygwin/bin$||')सभी भागने से रोकने के लिए।
मथायस कुह्न

17

बैश में:

directory_to_remove=/d/Programme/cygwin/bin
PATH=:$PATH:
PATH=${PATH//:$directory_to_remove:/:}
PATH=${PATH#:}; PATH=${PATH%:}

यदि आप एक मध्यवर्ती चर का उपयोग नहीं करते हैं, तो आपको /हटाने के लिए निर्देशिका में पात्रों की रक्षा करने की आवश्यकता है ताकि उन्हें खोज पाठ के अंत के रूप में न माना जाए।

PATH=:$PATH:
PATH=${PATH//:\/d\/Programme\/cygwin\/bin:/:}
PATH=${PATH#:}; PATH=${PATH%:}

पहली और तीसरी पंक्ति :में पहले और अंतिम घटक विशेष आवरण से बचने के लिए, खोज पथ के प्रत्येक घटक को घेरने की व्यवस्था है । दूसरी पंक्ति निर्दिष्ट घटक को हटा देती है।


धन्यवाद @Gilles, आपके उत्तर ने मुझे अपने स्वयं के समाधान के साथ आने के लिए प्रेरित किया , जिसके लिए केवल PATH के तीन जोड़तोड़ की आवश्यकता होती है, फिर चार। * 8 ')
मार्क बूथ

8

यहां प्रस्तुत अन्य विकल्पों पर विचार करने के बाद, और पूरी तरह से समझ में नहीं आया कि उनमें से कुछ ने कैसे काम किया मैंने अपना स्वयं का path_removeफ़ंक्शन विकसित किया , जिसे मैंने अपने साथ जोड़ा .bashrc:

function path_remove {
  # Delete path by parts so we can never accidentally remove sub paths
  PATH=${PATH//":$1:"/":"} # delete any instances in the middle
  PATH=${PATH/#"$1:"/} # delete any instance at the beginning
  PATH=${PATH/%":$1"/} # delete any instance in the at the end
}

यह गिल्स के समाधान के काफी करीब था, लेकिन इसे बैश फ़ंक्शन के रूप में लपेटा गया, जिसे आसानी से कमांड लाइन पर इस्तेमाल किया जा सकता था।

इसके फायदे हैं कि यह एक बैश फंक्शन के रूप में काम करता है, जो बिना किसी प्रोग्राम की तरह काम करता है, और इसे चलाने के लिए किसी बाहरी प्रोग्राम की जरूरत नहीं है, बस स्ट्रिंग हेरफेर करें।

यह बहुत मजबूत दिखाई देता है, विशेष रूप से इसे बंद नहीं करता है somepath:mypath/mysubpathमें somepath/mysubpath: यदि आप चलाने path_remove mypath, जो एक समस्या मैं अपने पिछले के साथ किया था path_removeसमारोह।

कैसे बैश स्ट्रिंग हेरफेर काम करता है की एक उत्कृष्ट विवरण उन्नत बैश-स्क्रिप्टिंग गाइड में पाया जा सकता है ।


6

तो, मैं @gilles और @ bruno-a (और कुछ अन्य सीड ट्रिक्स) के उत्तरों को जोड़कर इस एक-लाइनर के साथ आया, जो PATH से (हर) REMOVE_PART को हटा देगा, चाहे वह शुरुआत में हो, PATH का मध्य या अंत

PATH=$(REMOVE_PART="/d/Programme/cygwin/bin" sh -c 'echo ":$PATH:" | sed "s@:$REMOVE_PART:@:@g;s@^:\(.*\):\$@\1@"')

यह थोड़ा बेमानी है, लेकिन इसे एक हिट में करने में सक्षम होना अच्छा है। ;एक साथ दो अलग-अलग sed आदेशों में शामिल होने के लिए किया जाता है:

  • s@:$REMOVE_PART:@:@g(जो :$REMOVE_PART:एकल के साथ बदलता है :)
  • s@^:\(.*\):\$@\1@ (इको कमांड के साथ हमने जो प्रमुख और अनुगामी कॉलोन छोड़े हैं)

और इसी तरह की पंक्तियों के साथ, मैं सिर्फ एक-लाइनर के साथ PATH में ADD_PART जोड़ने के लिए आने में कामयाब रहा हूं, केवल अगर PATH में यह पहले से ही नहीं है

PATH=$(ADD_PART="/d/Programme/cygwin/bin" sh -c 'if echo ":$PATH:" | grep -q ":$ADD_PART:"; then echo "$PATH"; else echo "$ADD_PART:$PATH"; fi')

echo "$PATH:$ADD_PART"यदि आप प्रारंभ के बजाय PATH के अंत में ADD_PART जोड़ना चाहते हैं तो अंतिम भाग बदलें ।

...

... या इसे और भी आसान बनाने के लिए, remove_path_partसामग्री के साथ एक स्क्रिप्ट बनाएं

echo ":$PATH:" | sed "s@:$1:@:@g;s@^:\(.*\):\$@\1@"

और एक स्क्रिप्ट prepend_path_partसामग्री के साथ बुलाया

if echo ":$PATH:" | grep -q ":$1:"; then echo "$PATH"; else echo "$1:$PATH"; fi

और एक स्क्रिप्ट append_path_partसामग्री के साथ बुलाया

if echo ":$PATH:" | grep -q ":$1:"; then echo "$PATH"; else echo "$PATH:$1"; fi

उन्हें सभी निष्पादन योग्य बनाएं, और फिर उन्हें कॉल करें जैसे:

  • PATH=$(remove_path_part /d/Programme/cygwin/bin)
  • PATH=$(prepend_path_part /d/Programme/cygwin/bin)
  • PATH=$(append_path_part /d/Programme/cygwin/bin)

भले ही, मैं अपने आप को इतना कहना :-)


मुझे सुझाव पसंद है, विशेषकर स्क्रिप्ट के साथ विचार।
देवोलस

3

बहुत सरल एक लाइनर।

निर्यात पाथ = `गूंज $ पाथ | tr ":" "\ n" | grep -v "एनाकोंडा" | tr "\ n" ":" `


2

पथ चर से निर्देशिका को हटाने के लिए बैश फ़ंक्शन लिखना एक दिलचस्प अभ्यास है।

यहाँ कुछ कार्य हैं जो मैं अपने .bash * फाइलों में पथों के लिए निर्देशिकाओं को जोड़ने / पूर्व-प्रयोग करने के लिए करता हूँ। उनके पास डुप्लिकेट प्रविष्टियों को हटाने का गुण है, यदि कोई है, और किसी भी तरह के बृहदान्त्र से अलग पथ चर (PATH, MANPATH, INFOPATH, ...) के साथ काम करते हैं। remove_from फ़ंक्शन निर्देशिका को निकालता है।

# {app,pre}pend_to path-var-name dirpath
# remove_from path-var-name dirpath
#
# Functions to manipulate a path-style variable.  {app,pre}pend_to
# both remove any other instances of dirname before adding it to
# the start or end of the path-var-name variable.
#
# Calling example:
#   append_to PATH "/usr/local/bin"
#
# Uses eval to allow target path varname to be passed in.
function remove_from() {
  # add surrounging colons
  eval tmp_path=":\$${1}:"
  # if dir is already there, remove it
  (echo "${tmp_path}" | grep --silent ":${2}:") &&
    tmp_path=`echo "$tmp_path" | sed "s=:${2}:=:=g"`
  # remove surrounding colons
  tmp_path=`echo "$tmp_path" | sed 's=^:==; s=:$=='`
  eval export $1=\"$tmp_path\"
}
function append_to() {
  remove_from "$1" "$2"  # clean the path contents
  eval export $1=\"\$${1}:$2\"
}
function prepend_to() {
  remove_from "$1" "$2"  # clean the path contents
  eval export $1=\"${2}:\$$1\"
}

2

नीचे ग्रेग टार्सा के समाधान से संशोधित कोड हैं। यहां केवल बैश बिल्ड-इन कमांड का उपयोग किया जाता है। इस प्रकार, यह बहुत सारे कांटा () सिस्टम कॉल को बचाएगा।

# Calling example:
#   append_to PATH "/usr/local/bin"

function remove_from()
{
    local path="${1}"
    local dir="${2}"
    local -a dirs=()
    local old_ifs="${IFS}"
    IFS=":"
    set -- ${!path}
    while [ "$#" -gt "0" ]
    do
        [ "${1}" != "${dir}" ] && dirs+=("${1}")
        shift
        done
    eval "export ${path}=\"${dirs[*]}\""
    IFS="${old_ifs}"
}

function append_to()
{
    remove_from "${1}" "${2}"
    [ -d "${2}" ] || return
    if [ -n "${!1}" ]
    then
        eval "export ${1}=\"${!1}:${2}\""
    else
        eval "export ${1}=\"${2}\""
    fi
}

function prepend_to()
{
    remove_from "${1}" "${2}"
    [ -d "${2}" ] || return
    if [ -n "${!1}" ]
    then
        eval "export ${1}=\"${2}:${!1}\""
    else
        eval "export ${1}=\"${2}\""
    fi
}

1

तुषार के स्वीकृत उत्तर को पूरा करने / सुधारने के लिए, आप कर सकते हैं:

  • गैर-स्लेश सीमांकक का उपयोग करके पथ में स्लैश से बचने के लिए
  • sed मैन पेज के-e अनुसार विकल्प को छोड़ें : "यदि no -e, --expression, -f, या --file विकल्प दिया गया है, तो पहले गैर-विकल्प तर्क को व्याख्या करने के लिए sed स्क्रिप्ट के रूप में लिया जाता है।"
  • gसभी घटनाओं को दूर करने के लिए (वैश्विक) ध्वज का उपयोग करें

अंत में, यह कुछ इस तरह देता है:

PATH=$(echo "$PATH" | sed 's@:/home/wrong/dir$@@g')

0

वर्तमान उत्तर मेरी इसी समस्या को हल नहीं करते हैं कि मुझे कई रास्ते निकालने होंगे। ये सभी पथ एक निर्देशिका के उप-निर्देशिका हैं। उस मामले में, यह एक-लाइनर मेरे लिए काम करता है: (मान लीजिए कि पैटर्न है cygwin, यानी, सभी रास्तों को हटा देना जिसमें शामिल हैं cygwin)

pattern=cygwin; export PATH=$(echo $PATH|tr ':' '\n'|sed "\#${pattern}#d" |tr '\n' ':')
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.