আমি কীভাবে পরিষ্কারভাবে AT PATH এ যুক্ত করতে পারি?


31

আমি সম্ভাব্যভাবে একই পথটি একাধিকবার যুক্ত না করে $ PATH, সিস্টেম-প্রশস্ত বা কোনও পৃথক ব্যবহারকারীর জন্য জিনিস যুক্ত করার উপায় চাই।

এটি করতে চাওয়ার একটি কারণ হ'ল সংযোজনগুলি যুক্ত করা যেতে পারে .bashrc, যার জন্য লগইন প্রয়োজন হয় না এবং যেসব সিস্টেমে (যেমন) lightdmকখনও কল করে না সেগুলিতে এটি আরও কার্যকর .profile

আমি কীভাবে $ PATH থেকে ডুপ্লিকেটগুলি পরিষ্কার করতে পারি সে সম্পর্কে প্রশ্নগুলি সম্পর্কে সচেতন , তবে আমি নকলগুলি সরাতে চাই না । আমি যদি রাস্তাগুলি ইতিমধ্যে উপস্থিত না থাকে তবে কেবল পথ যুক্ত করার উপায় চাই



স্বর্ণা, কেন জানি না তবে আমি খালি আপনার প্রথম মন্তব্যটিও দেখেছি। তবে হ্যাঁ, নামের উপসর্গগুলিও কাজ করে, কোনও উদ্বেগ নেই! অন্যভাবে বন্ধ করাও ঠিক আছে।
সিরো সান্তিলি 新疆 改造 中心 法轮功 六四 事件

ঠিক আছে, আপনি যতক্ষণ আমার বার্তা পেয়েছেন। কখনও কখনও এর মতো বিপরীত ঘটনা কিছুটা বিশৃঙ্খলা সৃষ্টি করে, আমার ধারণা আমরা কী করব তা দেখব।
স্বর্ণলোকস

উত্তর:


35

মনে করুন যে আমরা যে নতুন পথটি যুক্ত করতে চাই তা হ'ল:

new=/opt/bin

তারপরে, কোনও পসিক্স শেল ব্যবহার করে, আমরা newইতিমধ্যে পথে রয়েছে কিনা তা পরীক্ষা করে দেখতে পারি এবং এটি না থাকলে এটি যুক্ত করতে পারি:

case ":${PATH:=$new}:" in
    *:"$new":*)  ;;
    *) PATH="$new:$PATH"  ;;
esac

কলোন ব্যবহার নোট করুন। কলোনগুলি ব্যতীত, আমরা ভাবতে পারি যে, বলুন, new=/binইতিমধ্যে পথে ছিল কারণ এটি প্যাটার্নটি মেলে /usr/bin। PATH- এ সাধারণত অনেকগুলি উপাদান থাকে, তবে শূন্যের বিশেষ ক্ষেত্রে এবং PATH- তে একটি উপাদানও পরিচালনা করা হয়। পাথ প্রাথমিকভাবে কোন উপাদান (খালি হচ্ছে) থাকার ক্ষেত্রে ব্যবহার দ্বারা পরিচালিত হয় এর ${PATH:=$new}জন্য যা নির্ধারণ PATHকরতে $newযদি এটা খালি। প্যারামিটারগুলির জন্য এইভাবে ডিফল্ট মান নির্ধারণ করা সমস্ত পসিক্স শেলের একটি বৈশিষ্ট্য: পসিক্স ডক্সের বিভাগ 2.6.2 দেখুন )

একটি কলযোগ্য ফাংশন

সুবিধার জন্য, উপরের কোডটি একটি ফাংশনে রাখা যেতে পারে। এই ফাংশনটি কমান্ড লাইনে সংজ্ঞায়িত করা যেতে পারে বা এটি স্থায়ীভাবে উপলভ্য হওয়ার জন্য, আপনার শেলের প্রারম্ভিক স্ক্রিপ্টে রাখা (বাশ ব্যবহারকারীদের জন্য, এটি হবে ~/.bashrc):

pupdate() { case ":${PATH:=$1}:" in *:"$1":*) ;; *) PATH="$1:$PATH" ;; esac; }

বর্তমান পথের ডিরেক্টরিতে ডিরেক্টরি যুক্ত করতে এই পাথ আপডেট ফাংশনটি ব্যবহার করতে:

pupdate /new/path

@ হ্যামার ঠিক আছে আমি তার জন্য একটি মামলা যুক্ত করেছি।
1024

1
আপনি 2 কেস পার্থক্য সংরক্ষণ করতে পারেন - সিএফ। unix.stackexchange.com/a/40973/1131
ম্যাক্সচলেপজিগ

3
যদি PATHখালি থাকে তবে এটিতে একটি খালি প্রবেশ (যেমন বর্তমান ডিরেক্টরি) যুক্ত করবে PATH। আমার মনে হয় আপনার আর একটি মামলা দরকার।
সিবি বেইলি

2
অন্য নয় @CharlesBailey case। শুধু কর case "${PATH:=$new}"। অনুরূপ ফলব্যাকগুলির জন্য আমার নিজের উত্তর দেখুন।
মাইক্রজারভ

1
@ এমসি0e আমি "লাইন-গোলমাল" লুকানোর জন্য কীভাবে শেল ফাংশন ব্যবহার করতে পারি তার একটি উদাহরণ যুক্ত করেছি।
1024

9

/etc/profile.dনামে পরিচিত একটি ফাইল তৈরি করুন , যেমন mypath.sh(বা আপনি যা চান)। আপনি যদি লাইটডিএম ব্যবহার করছেন, তা নিশ্চিত করুন যে এটি কার্যকর বা অন্যথায় ব্যবহার করুন /etc/bashrcবা এর থেকে উত্সযুক্ত কোনও ফাইল। নিম্নলিখিত ফাংশন যোগ করুন:

checkPath () {
        case ":$PATH:" in
                *":$1:"*) return 1
                        ;;
        esac
        return 0;
}

# Prepend to $PATH
prependToPath () {
        for a; do
                checkPath $a
                if [ $? -eq 0 ]; then
                        PATH=$a:$PATH
                fi
        done
        export PATH
}

# Append to $PATH
appendToPath () {
        for a; do
                checkPath $a
                if [ $? -eq 0 ]; then
                        PATH=$PATH:$a
                fi
        done
        export PATH
}

(প্রিপেন্ডেড) শুরুর দিকের বিষয়গুলি AT পথ অনুসরণ করে তার চেয়ে বেশি অগ্রাধিকার দেয় এবং এর বিপরীতে, শেষের দিকে (সংযোজিত) বিষয়গুলি যা ঘটেছিল তা দ্বারা প্রকাশ করা হবে। এর অর্থ যদি আপনার $ PATH থাকে /usr/local/bin:/usr/binএবং gotchaউভয় ডিরেক্টরিতে একটি এক্সিকিউটেবল থাকে তবে এর মধ্যে একটি /usr/local/binডিফল্টরূপে ব্যবহৃত হবে।

আপনি এখন - এই একই ফাইলে, অন্য শেল কনফিগার ফাইলে, বা কমান্ডলাইন থেকে - ব্যবহার করতে পারেন:

appendToPath /some/path /another/path
prependToPath /some/path /yet/another/path

এই একটি থাকে তাহলে .bashrc, এটা একবার যখন আপনি একটি নতুন শেল শুরু তুলনায় আরো উপস্থিত হওয়া থেকে মান প্রতিরোধ করবে। এর মধ্যে একটি সীমাবদ্ধতা রয়েছে যদি আপনি এমন কিছু সংযোজন করতে চান যা প্রিপেন্ড করা হয়েছিল (যেমন $ পাথের মধ্যে একটি পাথ সরিয়ে ফেলুন) বা তার বিপরীতে, আপনাকে এটি নিজেই করতে হবে।


এর $PATHসাথে বিভক্ত IFS=:করা চূড়ান্ত চেয়ে আরও নমনীয় case
মাইক্রজারভ

@ মিমকিজার সন্দেহ নেই। এটি caseআইএমওর জন্য এক ধরণের হ্যাক ব্যবহার । আমি awkএখানে খুব ভাল ব্যবহার করা যেতে পারে কল্পনা ।
স্বর্ণলোকস

এটা একটা ভাল দিক. এবং, আমি যেমন মনে করি, gawkসরাসরি বরাদ্দ করতে পারে $PATH
মাইক্রজারভ

5

আপনি এটি এইভাবে করতে পারেন:

echo $PATH | grep /my/bin >/dev/null || PATH=$PATH:/my/bin

দ্রষ্টব্য: আপনি যদি অন্য ভেরিয়েবল থেকে PATH তৈরি করেন তবে পরীক্ষা করুন যে সেগুলি খালি নেই, কারণ অনেকগুলি শেল "" এর মতো "ব্যাখ্যা করে।" ।


+1 -qমেন পৃষ্ঠা অনুসারে গ্রেপের জন্য পসিক্সের দ্বারা প্রয়োজনীয় আবশ্যক, তবে আমি জানি না এর অর্থ এখনও কিছু (নন পসিক্স) গ্রেপ রয়েছে যা না আছে।
স্বর্ণলোক

1
নোট করুন যে গ্রেপ প্যাটার্ন অত্যধিক বিস্তৃত। জিআরপি / আমার / বিন> / দেব / নাল পরিবর্তে egrep -q "(^ |:) / আমার / বিন (: | \ $)" ব্যবহারের কথা বিবেচনা করুন। এই সংশোধনটির মাধ্যমে আপনার সমাধানটি সঠিক, এবং আমি মনে করি এটি @ জন 1010 থেকে বর্তমানে পছন্দসই উত্তরের চেয়ে আরও পঠনযোগ্য সমাধান। নোট করুন যে আমি ডাবল কোট ব্যবহার করেছি তাই আপনি পরিবর্তনের পরিবর্তে বিকল্প ব্যবহার করুন/my/bin
mc0e

5

কোডের গুরুত্বপূর্ণ অংশটি PATHএকটি নির্দিষ্ট পাথ রয়েছে কিনা তা পরীক্ষা করা :

printf '%s' ":${PATH}:" | grep -Fq ":${my_path}:"

এটি নিশ্চিত করুন যে প্রতিটি পথ পৃথককারী ( ) দ্বারা উভয় পক্ষেই PATHসীমিত করা হয়েছে , তারপরে ( ) পরীক্ষা করুন ( ) আক্ষরিক স্ট্রিং ( ) একটি বিভাজক, আপনার পথ এবং অন্য বিভাজকের সমন্বয়ে সেখানে উপস্থিত রয়েছে কিনা তা পরীক্ষা করুন । যদি এটি না হয় তবে আপনি নিরাপদে পথটি যুক্ত করতে পারেন:PATH:-q-FPATHPATH

if ! printf '%s' ":${PATH-}:" | grep -Fq ":${my_path-}:"
then
    PATH="${PATH-}:${my_path-}"
fi

এটি পসিক্সের সাথে সামঞ্জস্যপূর্ণ হওয়া উচিত এবং নতুন লাইনের অক্ষর না থাকা এমন কোনও পথে কাজ করা উচিত। এটা আরো জটিল যদি আপনি এটি সম্পর্কে newline ধারণকারী POSIX সামঞ্জস্যপূর্ণ হচ্ছে যখন পাথ সাথে কাজ করতে চান, কিন্তু আপনি একটি আছে grepযা সমর্থন -zআপনি যে ব্যবহার করতে পারেন।


4

আমি এই ছোট্ট ফাংশনটি ~/.profileকয়েক বছর ধরে আমার সাথে বিভিন্ন ফাইলে বহন করে আসছি । আমার মনে হয় এটি সিসাদমিন লিখেছেন এমন একটি ল্যাবে যা আমি কাজ করতাম তবে আমি নিশ্চিত নই। যাইহোক, এটি গোল্ডিলকের পদ্ধতির অনুরূপ তবে কিছুটা পৃথক:

pathmunge () {
        if ! echo $PATH | /bin/grep -Eq "(^|:)$1($|:)" ; then
           if [ "$2" = "after" ] ; then
              PATH=$PATH:$1
           else
              PATH=$1:$PATH
           fi
        fi
}

সুতরাং, এর শুরুতে একটি নতুন ডিরেক্টরি যুক্ত করতে PATH:

pathmunge /new/path

এবং শেষ পর্যন্ত:

pathmunge /new/path after

এটি আমার পক্ষে কাজ করে! আমি ডিফল্টরূপে এটি পরে রাখার জন্য লজিকের পরিবর্তিত হয়েছি এবং "আগে" দিয়ে ওভাররাইড করেছি। :)
কেভিন পাওলি

প্যাথমুনেজটি লিনাক্স সেন্টো বিতরণ / ইত্যাদি / প্রোফাইলের অংশ, এর আগে এবং পরে একটি প্যারামিটার থাকে। আমি আমার সর্বশেষ উবুন্টু 16 এ এটি দেখতে পাচ্ছি না
কেমিন ঝো

ম্যাকোস 10.12 এর পরে /bin/grep->grep
বেন ক্র্যাসি

4

হালনাগাদ:

আমি লক্ষ্য করেছি যে আপনার নিজের উত্তরটিতে প্রতিটি যুক্ত বা প্রিপেন্ড করার জন্য আলাদা আলাদা ফাংশন রয়েছে $PATH। আমি ধারণা পছন্দ। তাই আমি সামান্য যুক্তি হ্যান্ডলিং যুক্ত। আমি _এটির যথাযথ নামকরণও করেছি:

_path_assign() { oFS=$IFS ; IFS=: ; add=$* ; unset P A ; A=
    set -- ${PATH:=$1} ; for p in $add ; do {
        [ -z "${p%-[AP]}" ] && { unset P A
                eval ${p#-}= ; continue ; }
        for d ; do [ -z "${d%"$p"}" ] && break
        done ; } || set -- ${P+$p} $* ${A+$p}
        done ; export PATH="$*" ; IFS=$oFS
}

% PATH=/usr/bin:/usr/yes/bin
% _path_assign \
    /usr/bin \
    /usr/yes/bin \
    /usr/bin/nope \
    -P \
    /usr/nope/bin \
    /usr/bin \
    -A \
    /nope/usr/bin \
    /usr/nope/bin

% echo $PATH

আউটপুট:

/usr/nope/bin:/usr/bin:/usr/yes/bin:/usr/bin/nope:/nope/usr/bin

ডিফল্টরূপে এটি -Aপ্রলম্বিত হবে $PATH, তবে আপনি নিজের আর্গুমেন্টের তালিকার যে কোনও জায়গায় -Pযোগ করে এই আচরণটি প্রতিশোধ নিতে পারেন -P। এটিকে আবার হাত দিয়ে আপনি এটিকে আবার -Aপেপেন্ডিংয়ে স্যুইচ করতে পারেন -A

নিরাপদ অভ্যাস

বেশিরভাগ ক্ষেত্রেই আমি লোকদের কোনওরকম ব্যবহার এড়ানো পরামর্শ দিই eval। তবে আমি মনে করি এটি ভাল ব্যবহারের উদাহরণ হিসাবে দাঁড়িয়েছে এক্ষেত্রে একমাত্র বিবৃতিটি eval কখনও দেখতে পাবে P=বা হয় A=। এটি যুক্ত হওয়ার আগে এর যুক্তিগুলির মানগুলি কঠোরভাবে পরীক্ষা করা হয়। এই কি eval জন্য হয়।

assign() { oFS=$IFS ; IFS=: ; add=$* 
    set -- ${PATH:=$1} ; for p in $add ; do { 
        for d ; do [ -z "${d%"$p"}" ] && break 
        done ; } || set -- $* $p ; done
    PATH="$*" ; IFS=$oFS
}

এটি যতটা আর্গুমেন্ট দেয় আপনি তা গ্রহণ করবেন এবং প্রতিটি $PATHএকবারে এবং একবারে যুক্ত করবেন যদি এটি ইতিমধ্যে প্রবেশ না করে $PATH। এটি কেবলমাত্র সম্পূর্ণ পোর্টেবল পসআইএক্স শেল-স্ক্রিপ্ট ব্যবহার করে, কেবল শেল বিল্ট-ইনগুলিতে নির্ভর করে এবং খুব দ্রুত।

% PATH=/usr/bin:/usr/yes/bin
% assign \
    /usr/bin \
    /usr/yes/bin \
    /usr/nope/bin \
    /usr/bin \
    /nope/usr/bin \
    /usr/nope/bin

% echo "$PATH"
> /usr/bin:/usr/yes/bin:/usr/nope/bin:/nope/usr/bin

@ টাফকা'গোল্ডিলকস এখানে আপডেট দেখুন - আপনি আমাকে অনুপ্রাণিত করেছেন।
মাইকজার্ভ

+1 কৌতূহলের বাইরে (সম্ভবত এটি একটি ভাল পৃথক প্রশ্নোত্তর উত্তর হতে পারে), _শেল ফাংশনগুলির উপসর্গগুলি তাদের "যথাযথ নেমস্পিড" তৈরি করে এমন ধারণাটি কোথা থেকে আসে? অন্যান্য ভাষায়, এটি সাধারণত একটি অভ্যন্তরীণ গ্লোবাল ফাংশন নির্দেশ করে (যেটি বিশ্বব্যাপী হওয়া দরকার তবে এটি কোনও এপিআইয়ের অংশ হিসাবে বহিরাগতভাবে ব্যবহার করার উদ্দেশ্যে নয়)। আমার নাম অবশ্যই দুর্দান্ত পছন্দ নয়, তবে আমার কাছে মনে হচ্ছে কেবল ব্যবহারের _ফলে সংঘর্ষের সমস্যাগুলি মোটেও সমাধান হয় না - প্রকৃত নেমস্পেসের উপর নজর রাখা ভাল ack mikeserv_path_assign()
স্বর্ণিলোক

@ টাফকা'গোল্ডিলকস - এটির সাথে আরও সুনির্দিষ্ট হওয়া আরও ভাল তবে নামটির ব্যবহার যত কম তত সহজ হবে gets তবে আপনার যদি পূর্ব নির্ধারিত কোনও যথাযথ এক্সিকিউটেবল বাইনারি থাকে _তবে আপনাকে প্যাকেজ পরিচালকদের স্যুইচ করতে হবে। যাই হোক না কেন, এটি মূলত কেবল "বৈশ্বিক, অভ্যন্তরীণ, ফাংশন" - এটি যে শেলটি ঘোষিত হয় তার থেকে প্রতিটি শেলের কাছে এটি বৈশ্বিক, এবং এটি দোভাষীর স্মৃতিতে ঝুলিয়ে রাখা কেবলমাত্র অনুবাদিত ভাষার লিপি is । unix.stackexchange.com/questions/120528/…
মাইকজারভ

আপনি কি unset aপ্রোফাইলের শেষে (বা সমমান) পারবেন না ?
সোর্সজেডি

0

দেখ! শিল্প-শক্তি 12-লাইন ... টেকনিক্যালি bash- এবং zsh-পোর্টেবল শেল ফাংশন যা দৃঢ়ভাবে ভালবাসে আপনার ~/.bashrcবা ~/.zshrcপছন্দের প্রারম্ভে স্ক্রিপ্ট:

# void +path.append(str dirname, ...)
#
# Append each passed existing directory to the current user's ${PATH} in a
# safe manner silently ignoring:
#
# * Relative directories (i.e., *NOT* prefixed by the directory separator).
# * Duplicate directories (i.e., already listed in the current ${PATH}).
# * Nonextant directories.
+path.append() {
    # For each passed dirname...
    local dirname
    for   dirname; do
        # Strip the trailing directory separator if any from this dirname,
        # reducing this dirname to the canonical form expected by the
        # test for uniqueness performed below.
        dirname="${dirname%/}"

        # If this dirname is either relative, duplicate, or nonextant, then
        # silently ignore this dirname and continue to the next. Note that the
        # extancy test is the least performant test and hence deferred.
        [[ "${dirname:0:1}" == '/' &&
           ":${PATH}:" != *":${dirname}:"* &&
           -d "${dirname}" ]] || continue

        # Else, this is an existing absolute unique dirname. In this case,
        # append this dirname to the current ${PATH}.
        PATH="${PATH}:${dirname}"
    done

    # Strip an erroneously leading delimiter from the current ${PATH} if any,
    # a common edge case when the initial ${PATH} is the empty string.
    PATH="${PATH#:}"

    # Export the current ${PATH} to subprocesses. Although system-wide scripts
    # already export the ${PATH} by default on most systems, "Bother free is
    # the way to be."
    export PATH
}

তাত্ক্ষণিক গৌরব জন্য নিজেকে প্রস্তুত। তারপরে, এটি না করে এবং ইচ্ছুকভাবে সেরাটির জন্য আশা করার চেয়ে:

export PATH=$PATH:~/opt/bin:~/the/black/goat/of/the/woods/with/a/thousand/young

পরিবর্তে এটি করুন এবং সর্বোত্তম হওয়ার গ্যারান্টিযুক্ত হোন, আপনি এমনকি সত্যই এটি চেয়েছিলেন বা না:

+path.append ~/opt/bin ~/the/black/goat/of/the/woods/with/a/thousand/young

ভেরি ওয়েল, "সেরা" সংজ্ঞা দিন।

নিরাপদে বর্তমানের উপর সংযোজন এবং প্রিন্টিং ${PATH}এটি সাধারণভাবে তৈরি হওয়া তুচ্ছ বিষয় নয়। সুবিধাজনক এবং আপাতদৃষ্টিতে বোধগম্য হওয়ার সময়, ফর্মের এক-লাইনার এতে export PATH=$PATH:~/opt/binশয়তানী জটিলতাগুলিকে আমন্ত্রণ জানায়:

  • দুর্ঘটনাক্রমে আপেক্ষিক নামকরণ (উদাঃ export PATH=$PATH:opt/bin)। যদিও bashএবং zshচুপি চুপি গ্রহণ এবং বেশিরভাগ আপেক্ষিক dirnames উপেক্ষা সবচেয়ে ক্ষেত্রে, আপেক্ষিক dirnames হয় এর পূর্বে সমাধান hবা t(এবং সম্ভবত অন্যান্য বদমাইশ অক্ষর) উভয় কারণ লজ্জাজনকভাবে নিজেদের Ala Masaki Kobayashi এর অঙ্গচ্ছেদ করা ধাতুগত 1962 মাষ্টারপিস Harakiri :

    # Don't try this at home. You will feel great pain.
    $ PATH='/usr/local/bin:/usr/bin:/bin' && export PATH=$PATH:harakiri && echo $PATH
    /usr/local/bin:/usr/bin:arakiri
    $ PATH='/usr/local/bin:/usr/bin:/bin' && export PATH=$PATH:tanuki/yokai && echo $PATH
    binanuki/yokai   # Congratulations. Your system is now face-up in the gutter.
    
  • দুর্ঘটনাক্রমে নকল নাম। ডুপ্লিকেট ${PATH}ডায়ারনেমগুলি যদিও বেশিরভাগ ক্ষেত্রে নিস্পাপ, তবুও এগুলি অযাচিত, জটিল, হালকাভাবে অক্ষম, ডিবাগিবিলিটি বাধাগ্রস্ত করে এবং ড্রাইভ পরিধান প্রচার করে - এই উত্তরের মতো সাজানো। যদিও ন্যানড-স্টাইলের এসএসডিগুলি ( অবশ্যই ) পরা পড়ার জন্য অনাক্রম্যতা রয়েছে, এইচডিডি নেই। প্রতিটি চেষ্টা করা কমান্ডে অপ্রয়োজনীয় ফাইল সিস্টেম অ্যাক্সেস একই টেম্পোতে অপ্রয়োজনীয় পঠিত মাথা পরিধান করে। নেস্টেড সাবপ্রোসেসেসে নেস্টেড শেলসকে ডাকার সময় সদৃশগুলি বিশেষত অস্পষ্ট হয়, যেখানে আপাতদৃষ্টিতে নির্দোষ ওয়ান-লাইনারগুলি export PATH=$PATH:~/watদ্রুত ${PATH}নরকের মতো সপ্তম বৃত্তে বিস্ফোরিত হয় PATH=/usr/local/bin:/usr/bin:/bin:/home/leycec/wat:/home/leycec/wat:/home/leycec/wat:/home/leycec/wat। আপনি যদি তখন অতিরিক্ত ডায়ারনাম যুক্ত করেন তবে কেবলমাত্র বেলজেবুবা আপনাকে সহায়তা করতে পারে। (আপনার মূল্যবান বাচ্চাদের ক্ষেত্রে এটি ঘটতে দেবেন না। )

  • দুর্ঘটনাবশত ডেরনাম মিস করছি। আবার, অনুপস্থিত ${PATH}ডেরনামগুলি মূলত নির্দোষ হয়ে ওঠার পরেও তারা সাধারণত অযাচিত, জটিল, হালকাভাবে অক্ষম, ডিবাগিবিলিটি বাধা দেয় এবং ড্রাইভ পরিধানকে প্রচার করে।

ইতিমধ্যে, উপরে সংজ্ঞায়িত শেল ফাংশনের মতো বন্ধুত্বপূর্ণ অটোমেশন। আমাদের নিজেদের থেকে নিজেকে বাঁচাতে হবে।

তবে ... কেন "+ path.append ()"? স্রেফ অ্যাপেন্ড_পথ () কেন নয়?

Disambiguity (যেমন, বর্তমান বাইরের কমান্ড সহ জন্য ${PATH}অথবা সিস্টেম-ব্যাপী শেল অন্যত্র সংজ্ঞায়িত ফাংশন), ব্যবহারকারী-সংজ্ঞায়িত শেল ফাংশন আদর্শভাবে পূর্বে সমাধান করা হয় বা দ্বারা সমর্থিত অনন্য সাবস্ট্রিং সঙ্গে suffixed bashএবং zshকিন্তু অন্যথায় মান কমান্ড basenames নিষিদ্ধ - মত, বলো, +

আরে। এটা কাজ করে। আমাকে বিচার করবেন না।

তবে ... কেন "+ path.append ()"? "+ Path.prepend ()" কেন নয়?

যেহেতু বর্তমানের সাথে সংযোজন বর্তমানের ${PATH}প্রিপেন্ডিংয়ের চেয়ে নিরাপদ ${PATH}, সমস্ত জিনিস সমান, যা সে কখনও হয় না। ব্যবহারকারী-নির্দিষ্ট কমান্ডগুলির সাথে সিস্টেম-ব্যাপী কমান্ডগুলি ওভাররাইড করা সর্বোত্তমভাবে নির্জনাত্মক হতে পারে এবং সবচেয়ে খারাপ সময়ে তৈরি হতে পারে। লিনাক্সের অধীনে, উদাহরণস্বরূপ, ডাউন স্ট্রিম অ্যাপ্লিকেশনগুলি সাধারণত কাস্টম অ-মানক ডেরাইভেটিভ বা বিকল্পগুলির পরিবর্তে জিএনইউ কোর্টিলস কমান্ডের রূপের প্রত্যাশা করে ।

এটি বলেছে যে, এটি করার জন্য বৈধ ব্যবহারের কেস অবশ্যই রয়েছে। সমতুল্য +path.prepend()ফাংশন সংজ্ঞায়িত করা তুচ্ছ। তার এবং তার ভাগ করা ধর্মহীনতার জন্য সান্স প্রোলিক্স নেবুলোসিটি:

+path.prepend() {
    local dirname
    for dirname in "${@}"; do
        dirname="${dirname%/}"
        [[ "${dirname:0:1}" == '/' &&
           ":${PATH}:" != *":${dirname}:"* &&
           -d "${dirname}" ]] || continue
        PATH="${dirname}:${PATH}"
    done
    PATH="${PATH%:}"
    export PATH
}

কিন্তু ... গিলস কেন নয়?

গিলেজ ' গৃহীত উত্তর অন্যত্র হিসেবে সাধারণ ক্ষেত্রে আকর্ষণীয় অনুকূল হয় "শেল অজ্ঞেয়বাদী idempotent পরিশেষে যোগ" । সাধারণ যদি bashএবং zshসঙ্গে কোন অবাঞ্ছিত symlinks অবশ্য পারফরম্যান্স শাস্তি তাই দুশ্চিন্তা করার প্রয়োজন জেন্টু ricer আমার মধ্যে। এমনকি অনাকাঙ্ক্ষিত প্রতীকগুলির উপস্থিতিতেও, add_to_PATH()যুক্তি অনুসারে একটি সাবসেল কাঁটা ফোটানো সিমিলিং ডুপ্লিকেটগুলির সম্ভাব্য সন্নিবেশের পক্ষে মূল্যবান কিনা তা বিতর্কযোগ্য ।

এমনকি সিমলিংক ডুপ্লিকেটগুলিও মুছে zshফেলার দাবি করে কঠোর ব্যবহারের ক্ষেত্রে, এই স্পেসিফিক বৈকল্পিকটি অদক্ষ কাঁটাচামচ না করে দক্ষ বিল্টিনগুলির মাধ্যমে এটি করে:

+path.append() {
    local dirname
    for   dirname in "${@}"; do
        dirname="${dirname%/}"
        [[ "${dirname:0:1}" == '/' &&
           ":${PATH}:" != *":${dirname:A}:"* &&
           -d "${dirname}" ]] || continue
        PATH="${PATH}:${dirname}"
    done
    PATH="${PATH#:}"
    export PATH
}

মূলটির *":${dirname:A}:"*চেয়ে বরং নোট করুন *":${dirname}:"*:Aএকটি বিস্ময়কর হল zshসহ - -ism দুঃখিতভাবে অন্যান্য অধিকাংশ শাঁস অধীনে অনুপস্থিত bash। উদ্ধৃতি হিসাবে man zshexpn:

উত্তর : aসংশোধক হিসাবে যেমন একটি ফাইলের নামকে একটি নিখুঁত পথে পরিণত করুন এবং তারপরে realpath(3)প্রতীকী লিঙ্কগুলি সমাধান করতে লাইব্রেরি ফাংশনের মাধ্যমে ফলাফলটি পাস করুন । দ্রষ্টব্য: যে সমস্ত সিস্টেমে realpath(3)লাইব্রেরি ফাংশন নেই, প্রতীকী লিঙ্কগুলি সমাধান করা হয় না, সেই পদ্ধতিগুলিতে aএবং Aসমতুল্য।

আর কোনো প্রশ্ন না.

আপনাকে স্বাগতম. নিরাপদ গোলাগুলি উপভোগ করুন। আপনি এখন এটি প্রাপ্য।


0

এখানে আমার কার্যকরী-প্রোগ্রামিং-শৈলী সংস্করণ।

  • *PATHকেবলমাত্র নয়, কোনও কোলন-সীমাবদ্ধ ভেরিয়েবলের জন্যও কাজ করে PATH
  • গ্লোবাল স্টেট অ্যাক্সেস করে না
  • কেবলমাত্র তার প্রদত্ত পরিবর্তনযোগ্য ইনপুটগুলির সাথে / এ কাজ করে
  • একক আউটপুট উত্পাদন করে
  • কোন পার্শ্ব প্রতিক্রিয়া
  • স্মরণযোগ্য (নীতিগতভাবে)

লক্ষণীয়:

  • exportআইএনজি সম্পর্কিত অজ্ঞেয়; এটি কলারের কাছে রেখে গেছে (উদাহরণ দেখুন)
  • খাঁটি bash; কোন কাঁটাচামচ না
path_add () {
  # $ 1: নিশ্চিতকরণের এলিমেন্টটি ঠিক একবারে প্রদত্ত পাথ স্ট্রিংয়ে রয়েছে
  # $ 2: বিদ্যমান পথের স্ট্রিংয়ের মান ("$ PATH", "PATH" নয়)
  # $ 3 (alচ্ছিক, কিছু): দেওয়া থাকলে given 1 যুক্ত করুন; অন্যথায়, প্রতিস্থাপন
  #
  # উদাহরণ:
  # $ রফতানি করুন PATH = $ (প্যাথ_অ্যাড '/ অপ্ট / বিন "" $ पथ ")
  # $ সিডিপ্যাথ = $ (পথ_আড্ডা '/ সঙ্গীত' "$ সিডিপিএটিএইচ" at_end)

  স্থানীয় -r ইতিমধ্যে_প্রেসেন্ট = "(^ |:) $ {1} ($ | :)"
  যদি [["$ 2" = ~ $ ইতিমধ্যে_ উপস্থিতি]]; তারপর
    প্রতিধ্বনি "$ 2"
  এলিফ [[$ # == 3]]; তারপর
    প্রতিধ্বনি "$ {2}: $ {1}"
  আর
    প্রতিধ্বনি "$ {1}: $ {2}"
  ফাই
}

0

এই স্ক্রিপ্টটি আপনাকে শেষে যোগ করতে দেয় $PATH:

PATH=path2; add_to_PATH after path1 path2:path3
echo $PATH
path2:path1:path3

বা এর শুরুতে যুক্ত করুন $PATH:

PATH=path2; add_to_PATH before path1 path2:path3
echo $PATH
path1:path3:path2

# Add directories to $PATH iff they're not already there
# Append directories to $PATH by default
# Based on https://unix.stackexchange.com/a/4973/143394
# and https://unix.stackexchange.com/a/217629/143394
add_to_PATH () {
  local prepend  # Prepend to path if set
  local prefix   # Temporary prepended path
  local IFS      # Avoid restoring for added laziness

  case $1 in
    after)  shift;; # Default is to append
    before) prepend=true; shift;;
  esac

  for arg; do
    IFS=: # Split argument by path separator
    for dir in $arg; do
      # Canonicalise symbolic links
      dir=$({ cd -- "$dir" && { pwd -P || pwd; } } 2>/dev/null)
      if [ -z "$dir" ]; then continue; fi  # Skip non-existent directory
      case ":$PATH:" in
        *":$dir:"*) :;; # skip - already present
        *) if [ "$prepend" ]; then
           # ${prefix:+$prefix:} will expand to "" if $prefix is empty to avoid
           # starting with a ":".  Expansion is "$prefix:" if non-empty.
            prefix=${prefix+$prefix:}$dir
          else
            PATH=$PATH:$dir  # Append by default
          fi;;
      esac
    done
  done
  [ "$prepend" ] && [ "$prefix" != "" ] && PATH=$prefix:$PATH
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.