বাশের $ PATH ভেরিয়েবল থেকে কোনও পথ মুছে ফেলার সর্বাধিক মার্জিত উপায় কী?


114

বা আরও সাধারণভাবে, আমি কীভাবে কোনও বাশ এনভায়রনমেন্ট ভেরিয়েবলের কোলন-বিচ্ছিন্ন তালিকা থেকে কোনও আইটেম সরিয়ে ফেলব?

আমি ভেবেছিলাম যে আমি বেশ কয়েক বছর আগে এটি করার সহজ উপায়টি দেখেছি, ব্যাশ ভেরিয়েবল প্রসারের আরও উন্নত রূপগুলি ব্যবহার করে, তবে যদি তাই হয় তবে আমি এটির ট্র্যাক হারিয়ে ফেলেছি। গুগলের একটি দ্রুত অনুসন্ধান আশ্চর্যজনকভাবে কয়েকটি প্রাসঙ্গিক ফলাফল প্রকাশ করেছে এবং এমন কোনও কিছুই নয় যে আমি "সরল" বা "মার্জিত" বলব। উদাহরণস্বরূপ, দু'টি পদ্ধতি যথাক্রমে সেড এবং অ্যাডকে ব্যবহার করুন:

PATH=$(echo $PATH | sed -e 's;:\?/home/user/bin;;' -e 's;/home/user/bin:\?;;')
PATH=!(awk -F: '{for(i=1;i<=NF;i++){if(!($i in a)){a[$i];printf s$i;s=":"}}}'<<<$PATH)

কোন কিছুর সোজা অস্তিত্ব নেই? বাশে বিভক্ত () ফাংশনের সাথে সাদৃশ্যপূর্ণ কিছু আছে কি?

আপডেট:
দেখে মনে হচ্ছে আমার উদ্দেশ্যমূলক-অস্পষ্ট প্রশ্নের জন্য আমাকে ক্ষমা চাইতে হবে; ভাল আলোচনা আলোচনার চেয়ে আমি নির্দিষ্ট ব্যবহার-মামলা সমাধানে আগ্রহী নই was ভাগ্যক্রমে, আমি পেয়েছি!

এখানে খুব চালাক কিছু কৌশল রয়েছে। শেষ পর্যন্ত, আমি আমার সরঞ্জামবক্সে নিম্নলিখিত তিনটি ফাংশন যুক্ত করেছি। ম্যাজিকটি পথ_ম্রোভে ঘটে যা মূলত মার্টিন ইয়র্ক এর awkআরএস ভেরিয়েবলের চালাক ব্যবহারের উপর ভিত্তি করে ।

path_append ()  { path_remove $1; export PATH="$PATH:$1"; }
path_prepend () { path_remove $1; export PATH="$1:$PATH"; }
path_remove ()  { export PATH=`echo -n $PATH | awk -v RS=: -v ORS=: '$0 != "'$1'"' | sed 's/:$//'`; }

সেখানে কেবলমাত্র আসল ক্রাফ্টটি হ'ল ট্রেলিং কোলনটি sedসরিয়ে ফেলতে হবে। মার্টিনের বাকী সমাধানটি কতটা সোজাসুজি বিবেচনা করে দেখুন, যদিও আমি এটির সাথে বাঁচতে বেশ ইচ্ছুক!


সম্পর্কিত প্রশ্ন: আমি কীভাবে শেল স্ক্রিপ্টগুলিতে AT PATH উপাদানগুলি ব্যবহার করব?


যে কোনও ভেরিয়েবলের জন্য: WORK=`echo -n ${1} | awk -v RS=: -v ORS=: '$0 != "'${3}'"' | sed 's/:$//'`; eval "export ${2}=${WORK}"তবে আপনাকে অবশ্যই এটি func $VAR VAR pattern(@ মার্টিন-ইয়র্ক এবং @ অ্যান্ড্রু-আইলেটটের উপর ভিত্তি করে) হিসাবে কল করতে হবে
ভেস্পের্টো

উত্তর:


51

বিশ্রাম সহ এক মিনিট:

# Strip all paths with SDE in them.
#
export PATH=`echo ${PATH} | awk -v RS=: -v ORS=: '/SDE/ {next} {print}'`

সম্পাদনা করুন: এটি নীচের মন্তব্যে প্রতিক্রিয়া:

$ export a="/a/b/c/d/e:/a/b/c/d/g/k/i:/a/b/c/d/f:/a/b/c/g:/a/b/c/d/g/i"
$ echo ${a}
/a/b/c/d/e:/a/b/c/d/f:/a/b/c/g:/a/b/c/d/g/i

## Remove multiple (any directory with a: all of them)
$ echo ${a} | awk -v RS=: -v ORS=: '/a/ {next} {print}'
## Works fine all removed

## Remove multiple including last two: (any directory with g)
$ echo ${a} | awk -v RS=: -v ORS=: '/g/ {next} {print}'
/a/b/c/d/e:/a/b/c/d/f:
## Works fine: Again!

সুরক্ষা সমস্যার প্রতিক্রিয়াতে সম্পাদনা করুন: (এটি প্রশ্নের সাথে প্রাসঙ্গিক নয়)

export PATH=$(echo ${PATH} | awk -v RS=: -v ORS=: '/SDE/ {next} {print}' | sed 's/:*$//')

এটি সর্বশেষ এন্ট্রিগুলি মোছার মাধ্যমে রেখে যাওয়া কোনও পেছনের কলোন সরিয়ে দেয়, যা কার্যকরভাবে .আপনার পথে যুক্ত হবে।


1
শেষ উপাদান বা একাধিক উপাদান অপসারণ করার চেষ্টা করার সময় ব্যর্থ: প্রথম ক্ষেত্রে এটি বর্তমান দিরকে (খালি স্ট্রিং হিসাবে; একটি সম্ভাব্য সুরক্ষা গর্ত হিসাবে) যোগ করে, দ্বিতীয় ক্ষেত্রে এটি একটি পাথ উপাদান হিসাবে adds adds যোগ করে।
ফ্রেড ফু

1
@ এলারসম্যানস: আমার পক্ষে ভাল কাজ করে। দ্রষ্টব্য: খালি বর্তমান ডিরেক্টরি হিসাবে একই নয় যা "./"
মার্টিন ইয়র্ক

2
একটি "সদস্য" হিসাবে একটি খালি স্ট্রিং PATHপরিবর্তনশীল করে , একটি বিশেষ নিয়ম হিসাবে, সমস্ত ইউনিক্স শেল 1979 এর পর থেকে অন্তত V7 ইউনিক্স এটা এখনও মধ্যে আছে এ বোঝাতে বর্তমান ডিরেক্টরী bash। ম্যানুয়ালটি পরীক্ষা করুন বা নিজের জন্য চেষ্টা করুন।
ফ্রেড ফু

1
@ মার্টিন: পসিক্সের এই আচরণের প্রয়োজন হয় না, তবে এটি নথি করে এবং এটির অনুমতি দেয়: pubs.opengroup.org/onlinepubs/9699919799/basedefs/…
ফ্রেড ফু

1
এটির সাথে সর্বশেষ উপাদানটি সরিয়ে দেওয়ার সময় আরও সূক্ষ্ম সমস্যা রয়েছে: অ্যাওআকে স্ট্রিংয়ের শেষে একটি নাল বাইট যুক্ত করা হবে বলে মনে হয় । এর অর্থ আপনি যদি পরে PATH তে অন্য কোনও ডিরেক্টরি সংযোজন করেন তবে বাস্তবে এটি অনুসন্ধান করা হবে না।
sschuberth

55

আমার নোংরা হ্যাক:

echo ${PATH} > t1
vi t1
export PATH=$(cat t1)

18
প্রক্রিয়াটি ডি- আউটমেট করার সবচেয়ে সুস্পষ্ট সমাধান হ'ল এটি কখনই ভাল লক্ষণ নয় । :-D
বেন ফাঁকা

"মার্জিত" বিকল্পগুলির চেয়ে অনেক বেশি নিরাপদ।
জর্স্টটেক

44

প্রতিস্থাপনের সাথে যেহেতু বড় ইস্যুটি শেষের মামলা, তাই শেষের কেসগুলি অন্যান্য মামলার চেয়ে আলাদা না করে কীভাবে? যদি পথটিতে ইতিমধ্যে শুরু এবং শেষের দিকে কলোন থাকে, তবে আমরা সহজেই আমাদের পছন্দসই স্ট্রিংটি কোলন দিয়ে আবৃত করতে পারি। যেমনটি হয়, আমরা সহজেই সেই কলোনগুলি যুক্ত করতে পারি এবং সেগুলি পরে সরাতে পারি।

# PATH => /bin:/opt/a dir/bin:/sbin
WORK=:$PATH:
# WORK => :/bin:/opt/a dir/bin:/sbin:
REMOVE='/opt/a dir/bin'
WORK=${WORK/:$REMOVE:/:}
# WORK => :/bin:/sbin:
WORK=${WORK%:}
WORK=${WORK#:}
PATH=$WORK
# PATH => /bin:/sbin

খাঁটি বাশ :)।


2
আমি কিছু অতিরিক্ত ফ্রস্টিংয়ের
সাইবার অলিভিয়র

1
আমি এটি ব্যবহার করেছি কারণ এটি সহজ সমাধানের মতো দেখায়। এটি অত্যন্ত দ্রুত এবং সহজ ছিল এবং আপনি সহজেই শেষ পংক্তির ঠিক আগে প্যাথ ভেরিয়েবল পরিবর্তন করার আগে ইকো $ ওয়ার্ক দিয়ে আপনার কাজটি খুব সহজেই পরীক্ষা করতে পারবেন।
ফিল গ্রান

2
একেবারে কিছুটা রত্ন। এই পোস্টটি পেয়ে আমি ঠিক কী করার চেষ্টা করছিলাম। - আপনাকে ধন্যবাদ অ্যান্ড্রু! বিটিডাব্লু: সম্ভবত আপনি ": $ पथ:" এর আশেপাশে ডাবল-কোট যুক্ত করতে চাইবেন, কেবলমাত্র যদি এর মধ্যে ফাঁকা স্থান ("/ usr / bin" সমান) থাকে এবং শেষ লাইনে "OR ওয়ার্ক" থাকে contain

2
ধন্যবাদ, @ প্যাকম্যান - :) আমি বেশ নিশ্চিত (কেবল এটি চেষ্টা করে দেখেছি) অ্যাসাইনমেন্টের জন্য আপনার স্পেসের দরকার নেই WORKএবং PATHভেরিয়েবল অ্যাসাইনমেন্ট এবং কমান্ড এক্সিকিউশন এর জন্য বিভাগে লাইনটি পার্স করার পরে ভেরিয়েবল এক্সপেনশন হওয়ার পরে। REMOVEউদ্ধৃতি দেওয়ার প্রয়োজন হতে পারে, বা আপনি যদি নিজের স্ট্রিংটি ধ্রুবক হন তবে প্রতিস্থাপনের মধ্যে সরাসরি রেখে দিতে পারেন।
অ্যান্ড্রু আইলেট

স্ট্রিংগুলি সংরক্ষণ করার সময় আমি সর্বদা বিভ্রান্ত হয়ে পড়েছিলাম, এভাবে আমি সর্বদা ডাবল-উদ্ধৃতি স্ট্রিংগুলি শুরু করি। এই পরিষ্কার করার জন্য আবার ধন্যবাদ। :)

26

এখানে আমি সবচেয়ে সহজ সমাধানটি প্রস্তুত করতে পারি:

#!/bin/bash
IFS=:
# convert it to an array
t=($PATH)
unset IFS
# perform any array operations to remove elements from the array
t=(${t[@]%%*usr*})
IFS=:
# output the new array
echo "${t[*]}"

উপরের উদাহরণটি us PATH এর যে কোনও উপাদানকে "usr" অন্তর্ভুক্ত করবে। সেই উপাদানটি সরাতে আপনি "/ usr *" "/ home / ব্যবহারকারী / বিন" এর সাথে প্রতিস্থাপন করতে পারেন।

প্রতি স্কুবার্থ আপডেট করুন

যদিও আমি মনে করি একটিতে ফাঁকা স্থানগুলি $PATHএকটি ভয়াবহ ধারণা, এখানে একটি সমাধান যা এটি পরিচালনা করে:

PATH=$(IFS=':';t=($PATH);n=${#t[*]};a=();for ((i=0;i<n;i++)); do p="${t[i]%%*usr*}"; [ "${p}" ] && a[i]="${p}"; done;echo "${a[*]}");

অথবা

IFS=':'
t=($PATH)
n=${#t[*]}
a=()
for ((i=0;i<n;i++)); do
  p="${t[i]%%*usr*}"
  [ "${p}" ] && a[i]="${p}"
done
echo "${a[*]}"

2
একটি লাইনার হিসাবে: PATH = $ (আইএফএস = ':'; টি = (AT পাথ); আনসেট আইএফএস; টি = ($ {টি [@] %% * usr *}); আইএফএস = ':'; প্রতিধ্বনি "$" {T [*]} ");
নিকেরোবট

1
এই সমাধানটি PATH- এ পাথের সাথে কাজ করে না যেখানে ফাঁকা স্থান রয়েছে; এটি কলোন দ্বারা তাদের প্রতিস্থাপন করে।
sschuberth

11

এখানে এমন এক-লাইনার যা বর্তমান গৃহীত এবং সর্বাধিক রেট দেওয়া উত্তর সত্ত্বেও , PATH এ অদৃশ্য অক্ষর যুক্ত করে না এবং ফাঁকা স্থানগুলি সহ যে রাস্তাগুলি মোকাবেলা করতে পারে:

export PATH=$(p=$(echo $PATH | tr ":" "\n" | grep -v "/cygwin/" | tr "\n" ":"); echo ${p%:})

ব্যক্তিগতভাবে, আমি এটি পড়তে / বুঝতে সহজেই পাই এবং এটি কেবল জঞ্জাল ব্যবহারের পরিবর্তে সাধারণ আদেশগুলি জড়িত।


2
... এবং আপনি যদি এমন কোনও কিছু চান যা export PATH=$(p=$(echo $PATH | tr ":" "\0" | grep -v -z "/cygwin/" | tr "\0" ":"); echo ${p%:})
ফাইলনামগুলিতে নতুন লাইনের সাথেও লড়াই

এটি আংশিক মিলগুলি সরিয়ে ফেলবে, যা সম্ভবত আপনি চান না; আমি ব্যবহার করব grep -v "^/path/to/remove\$"বাgrep -v -x "/path/to/remove"
শ্যাড স্টারলিং

দুর্দান্ত সমাধান, তবে আপনি কি মনে করেন trযে এর চেয়ে বেশি সাধারণ awk? ;)
কে। মাইকেল আয়ে

1
একেবারে। উইন্ডোজে গিট ব্যাশের মতো হালকা ওজনের পরিবেশের trপরিবর্তে একটি দোভাষী হিসাবে পছন্দ না করে একটি সাধারণ সরঞ্জাম নিয়ে আসে awk
স্কুবার্থ

1
@ehdr: আপনি প্রতিস্থাপন করা প্রয়োজন echo "..."সঙ্গে printf "%s" "..."এটা পছন্দ পাথ কাজ করার জন্য -eএবং অনুরূপ। দেখুন stackoverflow.com/a/49418406/102441
এরিক

8

এখানে একটি সমাধান যা:

  • খাঁটি বাশ,
  • অন্যান্য প্রক্রিয়া (যেমন 'সেড' বা 'অ্যাডক') চালায় না,
  • পরিবর্তন হয় না IFS,
  • একটি উপ-শেল কাঁটাচামচ করে না,
  • স্পেস সহ পাথ পরিচালনা করে এবং
  • যুক্তিটির সমস্ত উপস্থিতি সরিয়ে দেয় PATH

    সরানফ্র্যামপথ () {
       স্থানীয় পিডি
       পি = ": $ 1:"
       D = ": $ PATH-:"
       D = $ {ঘ // $ P /:}
       D = $ {ডি / #: /}
       পাথ = $ {ঘ /%: /}
    }

4
আমি এই সমাধানটি পছন্দ করি। ভেরিয়েবলের নামগুলি আরও বর্ণনামূলক করতে পারে?
অনুকুল

খুব সুন্দর. তবে, একটি তারকাচিহ্ন (*) যুক্ত পাথ বিভাগগুলির জন্য কাজ করে না। কখনও কখনও তারা দুর্ঘটনাক্রমে সেখানে পৌঁছে।
জার্গ

6

ফাংশন __path_remove () {
স্থানীয় ডি = ": $ AT पथ }:";
["$ {ডি /: $ 1: /:}"! = "$ ডি"] && PATH = "$ {ডি /: $ 1: /:}";
পাথ = "$ {path / #: /}";
PATH = "$ AT पथ /%: /}" রফতানি করুন;
}

আমার .bashrc ফাইল থেকে এটি খনন করুন। আপনি যখন পাথের সাথে চারপাশে খেলেন, এবং এটি হারিয়ে যায়, awk / সেড / গ্রেপ অনুপলব্ধ হয়ে যায় :-)


1
এটি একটি খুব ভাল পয়েন্ট। (আমি কখনই এর মতো সহজ জিনিসগুলির জন্য বাহ্যিক ইউটিলিটিগুলি সম্পাদন করার পছন্দ করি না)।

6

আমি এখন পর্যন্ত সবচেয়ে ভাল খাঁটি বাশ বিকল্পটি পেয়েছি:

function path_remove {
  PATH=${PATH/":$1"/} # delete any instances in the middle or at the end
  PATH=${PATH/"$1:"/} # delete any instances at the beginning
}

এই উপর ভিত্তি করে তৈরি পুরোপুরি সঠিক উত্তর করতে $ পথে ডিরেক্টরির যুক্ত করে থাকেন এটি আগে থেকেই ওখানে নেই ওভার superuser উপর।


এটিও বেশ ভাল। আমি এটি পরীক্ষা করেছি। যদি PATH এ যদি একটি সদৃশ পথ থাকে (উদাহরণস্বরূপ দুটি যা একেবারে একই) তবে তার মধ্যে একটি মাত্র সরানো হবে। আপনি এটিকে ওয়ান- removePath () { PATH=${PATH/":$1"/}; PATH=${PATH/"$1:"/}; }

$PATHলক্ষ্যটি একটি সাব-ফোল্ডার (অর্থ মুছে ফেলা) পাথায় থাকে তখন এই সমাধান ব্যর্থ হয় । উদাহরণস্বরূপ: a:abc/def/bin:b-> a/bin:b, কখন abc/defমুছতে হবে।
রবিন হু

5

আমি সবেমাত্র ব্যাশ বিতরণে ফাংশনগুলি ব্যবহার করছি, যেগুলি ১৯৯১ সাল থেকে সেখানে দৃশ্যত ছিল These এগুলি এখনও ফেডোরার ব্যাশ-ডক্স প্যাকেজে রয়েছে এবং ব্যবহৃত হবে /etc/profile, তবে আর নেই ...

$ rpm -ql bash-doc |grep pathfunc
/usr/share/doc/bash-4.2.20/examples/functions/pathfuncs
$ cat $(!!)
cat $(rpm -ql bash-doc |grep pathfunc)
#From: "Simon J. Gerraty" <sjg@zen.void.oz.au>
#Message-Id: <199510091130.VAA01188@zen.void.oz.au>
#Subject: Re: a shell idea?
#Date: Mon, 09 Oct 1995 21:30:20 +1000


# NAME:
#       add_path.sh - add dir to path
#
# DESCRIPTION:
#       These functions originated in /etc/profile and ksh.kshrc, but
#       are more useful in a separate file.
#
# SEE ALSO:
#       /etc/profile
#
# AUTHOR:
#       Simon J. Gerraty <sjg@zen.void.oz.au>

#       @(#)Copyright (c) 1991 Simon J. Gerraty
#
#       This file is provided in the hope that it will
#       be of use.  There is absolutely NO WARRANTY.
#       Permission to copy, redistribute or otherwise
#       use this file is hereby granted provided that
#       the above copyright notice and this notice are
#       left intact.

# is $1 missing from $2 (or PATH) ?
no_path() {
        eval "case :\$${2-PATH}: in *:$1:*) return 1;; *) return 0;; esac"
}
# if $1 exists and is not in path, append it
add_path () {
  [ -d ${1:-.} ] && no_path $* && eval ${2:-PATH}="\$${2:-PATH}:$1"
}
# if $1 exists and is not in path, prepend it
pre_path () {
  [ -d ${1:-.} ] && no_path $* && eval ${2:-PATH}="$1:\$${2:-PATH}"
}
# if $1 is in path, remove it
del_path () {
  no_path $* || eval ${2:-PATH}=`eval echo :'$'${2:-PATH}: |
    sed -e "s;:$1:;:;g" -e "s;^:;;" -e "s;:\$;;"`
}

4

আমি এখানে একটি উত্তর লিখেছিলাম (খুব ভাল শব্দ ব্যবহার করে)। তবে আমি নিশ্চিত নই যে আপনি যা খুঁজছেন? এটি কমপক্ষে একটি লাইনে ফিট করার চেষ্টা করার পরিবর্তে এটি কী করে তা আমার কাছে পরিষ্কার দেখাচ্ছে। একটি সহজ একটি লাইনারের জন্য, যদিও এটি কেবল স্টাফ সরিয়ে দেয়, আমি সুপারিশ করি

echo $PATH | tr ':' '\n' | awk '$0 != "/bin"' | paste -sd:

প্রতিস্থাপন করা হয়

echo $PATH | tr ':' '\n' | 
    awk '$0 != "/bin"; $0 == "/bin" { print "/bar" }' | paste -sd:

বা (ছোট তবে কম পাঠযোগ্য)

echo $PATH | tr ':' '\n' | awk '$0 == "/bin" { print "/bar"; next } 1' | paste -sd:

যাইহোক, একই প্রশ্ন এবং সম্পূর্ণ দরকারী উত্তরগুলির জন্য, এখানে দেখুন


এবং আপনি যদি কোনও লাইন মুছতে চান যা একটি আংশিক স্ট্রিং ব্যবহার রয়েছে awk '$0 !~ "/bin"'। অর্থাৎ অ্যাডক অপারেটরের সাথে '/ বিন' না থাকা লাইনগুলি রাখুন !~
thoni56

3

ঠিক আছে, ব্যাশে, এটি নিয়মিত প্রকাশকে সমর্থন করে, তবে আমি কেবল এটি করব:

PATH=${PATH/:\/home\/user\/bin/}

এটি কি কেবলমাত্র নামকরণের সম্প্রসারণ নয়, নিয়মিত অভিব্যক্তি নয়?
ড্রিমলাক্স

2
যদিও ব্যাশ নিয়মিত এক্সপ্রেশন সমর্থন করে (বাশ 3 হিসাবে) এটি এটির উদাহরণ নয়, এটি একটি পরিবর্তনশীল প্রতিস্থাপন।
রবার্ট গ্যাম্বল

4
এটি প্যাটার্নের পরিবর্তনশীল বিস্তৃতি এবং সমাধানটিতে বেশ কয়েকটি সমস্যা রয়েছে। 1) এটি প্রথম উপাদানটির সাথে মেলে না। ২) এটি "/ হোম / ইউজার / বিন" দিয়ে শুরু হওয়া যে কোনও কিছুতেই কেবল "/ হোম / ইউজার / বিন" দিয়ে মেলে না। 3) এটির জন্য বিশেষ অক্ষরগুলি রক্ষা করা দরকার। সর্বোপরি, আমি বলতে চাই এটি একটি অসম্পূর্ণ উদাহরণ।
নিকেরোবট

2

আমি @ বেনব্ল্যাঙ্কের তার মূল প্রশ্নের আপডেটে প্রদর্শিত তিনটি ফাংশনটি পছন্দ করি। এগুলিকে সাধারণীকরণের জন্য, আমি একটি 2-যুক্তিযুক্ত ফর্ম ব্যবহার করি, যা আমাকে PATH বা অন্য যে কোনও পরিবেশের পরিবর্তনশীল যা আমার সেট করতে দেয়:

path_append ()  { path_remove $1 $2; export $1="${!1}:$2"; }
path_prepend () { path_remove $1 $2; export $1="$2:${!1}"; }
path_remove ()  { export $1="`echo -n ${!1} | awk -v RS=: -v ORS=: '$1 != "'$2'"' | sed 's/:$//'`"; }

ব্যবহারের উদাহরণ:

path_prepend PATH /usr/local/bin
path_append PERL5LIB "$DEVELOPMENT_HOME/p5/src/perlmods"

দ্রষ্টব্য যে আমি শূন্যস্থানগুলি সহ সঠিকরূপে প্রক্রিয়াকরণের অনুমতি দেওয়ার জন্য কিছু উদ্ধৃতি চিহ্নও যুক্ত করেছি added


2

বাশের $ PATH ভেরিয়েবল থেকে কোনও পথ মুছে ফেলার সর্বাধিক মার্জিত উপায় কী?

এওকের চেয়ে মার্শাল আর কি?

path_remove ()  { export PATH=`echo -n $PATH | awk -v RS=: -v ORS=: '$0 != "'$1'"' | sed 's/:$//'`; 

পাইথন! এটি একটি আরও পঠনযোগ্য এবং রক্ষণাবেক্ষণযোগ্য সমাধান এবং আপনি যা চান তা সত্যিই এটি করছে তা দেখতে এটি পরীক্ষা করা সহজ।

আপনি কি প্রথম পথের উপাদানটি মুছতে চান?

PATH="$(echo "$PATH" | python -c "import sys; path = sys.stdin.read().split(':'); del path[0]; print(':'.join(path))")"

(পরিবর্তে থেকে বংশীধ্বনিতুল্য এর echo, os.getenv['PATH']একটু খাটো হবে এবং উপরের মতো একই ফলাফল প্রদান করা, কিন্তু আমি চিন্তিত যে পাইথন পরিবেশ পরিবর্তনশীল সঙ্গে কিছু কি হতে পারে আছি, তাই এটি পরিবেশ আপনার পছন্দের থেকে এটা সরাসরি পাইপ সম্ভবত সেরা ।)

একইভাবে শেষ থেকে অপসারণ:

PATH="$(echo "$PATH" | python -c "import sys; path = sys.stdin.read().split(':'); del path[-1]; print(':'.join(path))")"

এই পুনরায় ব্যবহারযোগ্য শেল ফাংশনগুলি তৈরি করতে আপনি করতে পারেন, উদাহরণস্বরূপ, আপনার .bashrc ফাইলে আটকে দিন:

strip_path_first () {
    PATH="$(echo "$PATH" | 
    python -c "import sys; path = sys.stdin.read().split(':'); del path[0]; print(':'.join(path))")"
}

strip_path_last () {
    PATH="$(echo "$PATH" | 
    python -c "import sys; path = sys.stdin.read().split(':'); del path[-1]; print(':'.join(path))")"
}

1

হ্যাঁ, PATH এর শেষে একটি কোলন স্থাপন, উদাহরণস্বরূপ, কোনও পথ অপসারণকে কিছুটা কম আনাড়ি এবং ত্রুটি-প্রবণ করে তোলে।

path_remove ()  { 
   declare i newPATH
   newPATH="${PATH}:"
   for ((i=1; i<=${#@}; i++ )); do
      #echo ${@:${i}:1}
      newPATH="${newPATH//${@:${i}:1}:/}" 
   done
   export PATH="${newPATH%:}" 
   return 0; 
} 

path_remove_all ()  {
   declare i newPATH
   shopt -s extglob
   newPATH="${PATH}:"
   for ((i=1; i<=${#@}; i++ )); do
      newPATH="${newPATH//+(${@:${i}:1})*([^:]):/}" 
      #newPATH="${newPATH//+(${@:${i}:1})*([^:])+(:)/}" 
   done
   shopt -u extglob 
   export PATH="${newPATH%:}" 
   return 0 
} 

path_remove /opt/local/bin /usr/local/bin

path_remove_all /opt/local /usr/local 

1

আপনি যদি $ PATH- তে নকল সরিয়ে ফেলার বিষয়ে উদ্বিগ্ন হন তবে সবচেয়ে মার্জিত উপায়, IMHO, এগুলিকে প্রথম স্থানে যুক্ত করা উচিত নয়। 1 লাইনে:

if ! $( echo "$PATH" | tr ":" "\n" | grep -qx "$folder" ) ; then PATH=$PATH:$folder ; fi

$ ফোল্ডারটি যে কোনও কিছু দ্বারা প্রতিস্থাপন করা যেতে পারে এবং এতে ফাঁকা স্থান ("/ হোম / ব্যবহারকারী / আমার নথি") থাকতে পারে


1

আমি আজ পর্যন্ত খুঁজে পেয়েছি সবচেয়ে মার্জিত খাঁটি বাশ সমাধান:

pathrm () {                                                                      
  local IFS=':'                                                                  
  local newpath                                                                  
  local dir                                                                      
  local pathvar=${2:-PATH}                                                       
  for dir in ${!pathvar} ; do                                                    
    if [ "$dir" != "$1" ] ; then                                                 
      newpath=${newpath:+$newpath:}$dir                                          
    fi                                                                           
  done                                                                           
  export $pathvar="$newpath"                                                        
}

pathprepend () {                                                                 
  pathrm $1 $2                                                                   
  local pathvar=${2:-PATH}                                                       
  export $pathvar="$1${!pathvar:+:${!pathvar}}"                                  
}

pathappend () {                                                                    
  pathrm $1 $2                                                                   
  local pathvar=${2:-PATH}                                                       
  export $pathvar="${!pathvar:+${!pathvar}:}$1"                                  
} 

1

অন্যান্য প্রস্তাবিত সমাধানগুলির মধ্যে বেশিরভাগ কেবল স্ট্রিং মেলিংয়ের উপর নির্ভর করে এবং যেমন , বা ., এর বিশেষ নাম সম্বলিত পাথ সেগমেন্টগুলিকে গ্রহণ করে না । যৌক্তিক ডিরেক্টরি ম্যাচগুলির পাশাপাশি স্ট্রিংয়ের ম্যাচগুলি অনুসন্ধান করতে নীচের বাশ ফাংশনটি তার যুক্তিতে এবং পাথ বিভাগে ডিরেক্টরিটির স্ট্রিংগুলি সমাধান করে।..~

rm_from_path() {
  pattern="${1}"
  dir=''
  [ -d "${pattern}" ] && dir="$(cd ${pattern} && pwd)"  # resolve to absolute path

  new_path=''
  IFS0=${IFS}
  IFS=':'
  for segment in ${PATH}; do
    if [[ ${segment} == ${pattern} ]]; then             # string match
      continue
    elif [[ -n ${dir} && -d ${segment} ]]; then
      segment="$(cd ${segment} && pwd)"                 # resolve to absolute path
      if [[ ${segment} == ${dir} ]]; then               # logical directory match
        continue
      fi
    fi
    new_path="${new_path}${IFS}${segment}"
  done
  new_path="${new_path/#${IFS}/}"                       # remove leading colon, if any
  IFS=${IFS0}

  export PATH=${new_path}
}

টেস্ট:

$ mkdir -p ~/foo/bar/baz ~/foo/bar/bif ~/foo/boo/bang
$ PATH0=${PATH}
$ PATH=~/foo/bar/baz/.././../boo/././../bar:${PATH}  # add dir with special names
$ rm_from_path ~/foo/boo/../bar/.  # remove same dir with different special names
$ [ ${PATH} == ${PATH0} ] && echo 'PASS' || echo 'FAIL'

বাক্সের বাইরে প্লাস ওয়ান
মার্টিন ইয়র্ক

1

স্ক্র্যাচ থেকে লিনাক্স এতে তিনটি বাশ ফাংশন সংজ্ঞায়িত করে /etc/profile:

# Functions to help us manage paths.  Second argument is the name of the
# path variable to be modified (default: PATH)
pathremove () {
        local IFS=':'
        local NEWPATH
        local DIR
        local PATHVARIABLE=${2:-PATH}
        for DIR in ${!PATHVARIABLE} ; do
                if [ "$DIR" != "$1" ] ; then
                  NEWPATH=${NEWPATH:+$NEWPATH:}$DIR
                fi
        done
        export $PATHVARIABLE="$NEWPATH"
}

pathprepend () {
        pathremove $1 $2
        local PATHVARIABLE=${2:-PATH}
        export $PATHVARIABLE="$1${!PATHVARIABLE:+:${!PATHVARIABLE}}"
}

pathappend () {
        pathremove $1 $2
        local PATHVARIABLE=${2:-PATH}
        export $PATHVARIABLE="${!PATHVARIABLE:+${!PATHVARIABLE}:}$1"
}

export -f pathremove pathprepend pathappend

সূত্র: http://www.linuxfromscratch.org/blfs/view/svn/postlfs/profile.html


1

আমি জানি এই প্রশ্নটি BASH সম্পর্কে জিজ্ঞাসা করে, যা সবার পছন্দ করা উচিত, তবে যেহেতু আমি প্রতিসামগ্রী উপভোগ করি এবং কখনও কখনও আমার "সিএসএস" ব্যবহার করা প্রয়োজন, তাই আমি "পাথ_প্রেড ()", "পাথ_অ্যাপেন্ড ()" এবং "পাথ_ম্রোভের সমতুল্য তৈরি করেছি () "উপরে মার্জিত সমাধান।

সারাংশটি হ'ল "সিএসএস" এর কোনও কার্যকারিতা নেই, তাই আমি আমার ব্যক্তিগত বিন ডিরেক্টরিতে সামান্য শেল স্ক্রিপ্টগুলি রাখি যা ফাংশনগুলির মতো কাজ করে। আমি মনোনীত পরিবেশের পরিবর্তনশীল পরিবর্তনগুলি করতে sc স্ক্রিপ্টগুলিতে উত্সগুলি তৈরি করি।

~ / বিন / _path_remove.csh:

set _resolve = `eval echo $2`
setenv $1 `eval echo -n \$$1 | awk -v RS=: -v ORS=: '$1 != "'${_resolve}'"' | sed 's/:$//'`;
unset _resolve

~ / বিন / _path_append.csh:

source ~/bin/_path_remove.csh $1 $2
set _base = `eval echo \$$1`
set _resolve = `eval echo $2`
setenv $1 ${_base}:${_resolve}
unset _base _resolve

~ / বিন / _path_prepend.csh:

source ~/bin/_path_remove.csh $1 $2
set _base = `eval echo \$$1`
set _resolve = `eval echo $2`
setenv $1 ${_resolve}:${_base}
unset _base _resolve

~ / বিন / .cshrc:


alias path_remove  "source ~/bin/_path_remove.csh  '\!:1' '\!:2'"
alias path_append  "source ~/bin/_path_append.csh  '\!:1' '\!:2'"
alias path_prepend "source ~/bin/_path_prepend.csh '\!:1' '\!:2'"

আপনি তাদের এগুলি ব্যবহার করতে পারেন ...

%(csh)> path_append MODULEPATH ${HOME}/modulefiles

0

যেহেতু এটি বেশ সমস্যাজনক হিসাবে দেখা যায়, যেমন কোনও মার্জিত উপায় নেই, তাই আমি সমাধানটি পুনরায় সাজিয়েই সমস্যাটি এড়িয়ে চলার পরামর্শ দিচ্ছি: এটি ছিন্ন করতে চেষ্টা করার পরিবর্তে আপনার পথ তৈরি করুন।

আমি যদি আপনার প্রকৃত সমস্যার প্রসঙ্গটি জানতাম তবে আমি আরও নির্দিষ্ট হতে পারি। অন্তর্বর্তী সময়ে, আমি প্রসঙ্গ হিসাবে একটি সফ্টওয়্যার বিল্ড ব্যবহার করব।

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

উদাহরণস্বরূপ, আমার কাছে একটি মাভেন-ভিত্তিক ওয়েবলজিক-লক্ষ্যযুক্ত জাভা বিল্ড রয়েছে যা আমি আমার নতুন নিয়োগকর্তাকে পেয়েছি। বিল্ড স্ক্রিপ্টটি ভঙ্গুর হওয়ার জন্য কুখ্যাত, এবং আরেকজন নতুন কর্মচারী এবং আমি আমাদের মেশিনগুলিতে কাজ করতে এটি পেতে তিন সপ্তাহ (পুরো সময় নয়, কেবল এখানে এবং সেখানেই, তবে এখনও অনেক ঘন্টা) ব্যয় করেছি। একটি অত্যাবশ্যক পদক্ষেপটি ছিল আমি প্যাথের নিয়ন্ত্রণ নিয়েছিলাম যাতে আমি ঠিক বুঝতে পারি কোন জাভা, কোন ম্যাভেন এবং কোন ওয়েবলজিককে ডাকা হচ্ছে। আমি সেই সমস্ত সরঞ্জামগুলির প্রতি নির্দেশ করতে পরিবেশের ভেরিয়েবল তৈরি করেছি, তারপরে আমি সেইগুলি আরও কয়েকজনকে ভিত্তিতে PATH গণনা করেছি। অবশেষে আমরা একটি পুনরুত্পাদনযোগ্য বিল্ড তৈরি না করা পর্যন্ত অনুরূপ কৌশলগুলি অন্যান্য কনফিগারযোগ্য সেটিংসকে জালিয়াতি করে।

যাইহোক, মাভেন ব্যবহার করবেন না, জাভা ঠিক আছে, এবং কেবলমাত্র ওয়েবলোগিক কিনুন যদি আপনার একেবারে ক্লাস্টারিংয়ের প্রয়োজন হয় (তবে অন্যথায় না, এবং বিশেষত এর মালিকানা বৈশিষ্ট্যগুলি নয়)।

শুভ কামনা.


কখনও কখনও আপনার রুট অ্যাক্সেস থাকে না এবং আপনার প্রশাসক আপনার পরিচালনা করে PATH। অবশ্যই, আপনি নিজের মালিকানা তৈরি করতে পারতেন তবে প্রতিবার আপনার প্রশাসক কিছু সরালে আপনি কোথায় রেখেছেন তা নির্ধারণ করতে হবে। এই ধরণের একটি প্রশাসক থাকার উদ্দেশ্য পরাস্ত করে।
শেপ

0

@ লিটিব হিসাবে, আমি " আমি কীভাবে শেল স্ক্রিপ্টগুলিতে " প্যাথ উপাদানগুলি ব্যবহার করি "এই প্রশ্নের উত্তরে অবদান রেখেছিলাম, সুতরাং আমার মূল উত্তরটি সেখানে রয়েছে।

'স্প্লিট' কার্যকারিতা bashএবং অন্যান্য বোর্ন শেল ডেরিভেটিভস $IFSআন্তঃ-ক্ষেত্র বিভাজক দ্বারা সর্বাধিক ঝরঝরেভাবে অর্জন করা হয় । উদাহরণস্বরূপ, অবস্থানগত আর্গুমেন্টগুলি (সেট করতে $1, $2, ...) পাথ, ব্যবহারের উপাদান:

set -- $(IFS=":"; echo "$PATH")

যতক্ষণ না H PATH এ কোনও স্থান নেই সেখানে এটি ঠিক আছে। স্পেস যুক্ত পথের উপাদানগুলির জন্য এটি কাজ করা একটি তুচ্ছ-ব্যায়াম - আগ্রহী পাঠকের জন্য রেখে দেওয়া। পার্লের মতো স্ক্রিপ্টিং ভাষা ব্যবহার করে এটি মোকাবেলা করা সম্ভবত সহজ।

আমার কাছে একটি স্ক্রিপ্টও রয়েছে, clnpathযা আমি আমার প্যাথ সেট করার জন্য ব্যাপকভাবে ব্যবহার করি। " সিএসএস-এ PATH ভেরিয়েবলের সদৃশ থেকে কীভাবে রাখা যায় " এই উত্তরে আমি এটি নথিভুক্ত করেছি ।


আইএফএস =: এ = (AT পাথ); আইএফএস = বিভাজনও দুর্দান্ত। যদি তাদের খুব ফাঁকা স্থান থাকে তবে কাজ করে। তবে তারপরে আপনি একটি অ্যারে পেয়েছেন, এবং নামগুলি মুছে ফেলার জন্য লুপগুলি এবং এর সাথে ঝাঁকুনি দিতে হবে।
জোহানেস স্কাউব - লিটব

হ্যাঁ; এটি ম্লান হয়ে যায় - আমার আপডেট হওয়া মন্তব্যের মতো, সম্ভবত এই সময়ে একটি স্ক্রিপ্টিং ভাষা ব্যবহার করা সহজ।
জোনাথন লেফলার

0

এই সমস্যাটি যেটি বিরক্তিকর করে তোলে তা হ'ল প্রথম এবং শেষ উপাদানগুলির মধ্যে ফেন্সিপোস্টের ঘটনা। আইএফএস পরিবর্তন করে এবং একটি অ্যারে ব্যবহার করে সমস্যাটি মার্জিতভাবে সমাধান করা যেতে পারে, তবে পথটি অ্যারে ফর্ম রূপান্তরিত হওয়ার পরে কোলনটি কীভাবে পুনরায় পরিচিত করতে হবে তা আমি জানি না।

এখানে একটি সামান্য কম মার্জিত সংস্করণ যা $PATHকেবল একটি স্ট্রিং ম্যানিপুলেশন ব্যবহার করে একটি ডিরেক্টরি সরিয়ে দেয় । আমি এটি পরীক্ষা করেছি।

#!/bin/bash
#
#   remove_from_path dirname
#
#   removes $1 from user's $PATH

if [ $# -ne 1 ]; then
  echo "Usage: $0 pathname" 1>&2; exit 1;
fi

delendum="$1"
NEWPATH=
xxx="$IFS"
IFS=":"
for i in $PATH ; do
  IFS="$xxx"
  case "$i" in
    "$delendum") ;; # do nothing
    *) [ -z "$NEWPATH" ] && NEWPATH="$i" || NEWPATH="$NEWPATH:$i" ;;
  esac
done

PATH="$NEWPATH"
echo "$PATH"

0

এখানে পার্ল ওয়ান-লাইনার রয়েছে:

PATH=`perl -e '$a=shift;$_=$ENV{PATH};s#:$a(:)|^$a:|:$a$#$1#;print' /home/usr/bin`

$aপরিবর্তনশীল পথ অপসারণ করা হবে পায়। s(বিকল্প) এবং printকমান্ড পরোক্ষভাবে কাজ $_পরিবর্তনশীল।


0

এখানে ভাল জিনিস। আমি প্রথমে ডুপস যুক্ত করা থেকে বিরত রাখতে এইটিকে ব্যবহার করি।

#!/bin/bash
#
######################################################################################
#
# Allows a list of additions to PATH with no dupes
# 
# Patch code below into your $HOME/.bashrc file or where it
# will be seen at login.
#
# Can also be made executable and run as-is.
#
######################################################################################

# add2path=($HOME/bin .)                  ## uncomment space separated list 
if [ $add2path ]; then                    ## skip if list empty or commented out
for nodup in ${add2path[*]}
do
    case $PATH in                 ## case block thanks to MIKE511
    $nodup:* | *:$nodup:* | *:$nodup ) ;;    ## if found, do nothing
    *) PATH=$PATH:$nodup          ## else, add it to end of PATH or
    esac                          ## *) PATH=$nodup:$PATH   prepend to front
done
export PATH
fi
## debug add2path
echo
echo " PATH == $PATH"
echo

1
আপনি PATH স্ট্রিংয়ে একটি শীর্ষস্থানীয় এবং অনুসরণকারী কোলন যুক্ত করে আপনার কেস স্টেটমেন্টটি সহজ করতে পারেন:case ":$PATH:" in (*:"$nodup":*) ;; (*) PATH="$PATH:$nodup" ;; esac
গ্লেন জ্যাকম্যান

0

বর্ধিত গ্লোববিং সক্ষম করার সাথে নিম্নলিখিতগুলি করা সম্ভব:

# delete all /opt/local paths in PATH
shopt -s extglob 
printf "%s\n" "${PATH}" | tr ':' '\n' | nl
printf "%s\n" "${PATH//+(\/opt\/local\/)+([^:])?(:)/}" | tr ':' '\n' | nl 

man bash | less -p extglob

0

প্রসারিত ওয়ান-লাইনার গ্লোবিং (ভাল, সাজানো):

path_remove ()  { shopt -s extglob; PATH="${PATH//+(${1})+([^:])?(:)/}"; export PATH="${PATH%:}"; shopt -u extglob; return 0; } 

$ 1 এ স্ল্যাশ পালানোর দরকার নেই বলে মনে হচ্ছে।

path_remove ()  { shopt -s extglob; declare escArg="${1//\//\\/}"; PATH="${PATH//+(${escArg})+([^:])?(:)/}"; export PATH="${PATH%:}"; shopt -u extglob; return 0; } 

0

পাঠে কলোন যুক্ত করা আমরা এর মতো কিছু করতে পারি:

path_remove ()  { 
   declare i newPATH
   # put a colon at the beginning & end AND double each colon in-between
   newPATH=":${PATH//:/::}:"   
   for ((i=1; i<=${#@}; i++)); do
       #echo ${@:${i}:1}
       newPATH="${newPATH//:${@:${i}:1}:/}"   # s/:\/fullpath://g
   done
   newPATH="${newPATH//::/:}"
   newPATH="${newPATH#:}"      # remove leading colon
   newPATH="${newPATH%:}"      # remove trailing colon
   unset PATH 
   PATH="${newPATH}" 
   export PATH
   return 0 
} 


path_remove_all ()  {
   declare i newPATH extglobVar
   extglobVar=0
   # enable extended globbing if necessary
   [[ ! $(shopt -q extglob) ]]  && { shopt -s extglob; extglobVar=1; }
   newPATH=":${PATH}:"
   for ((i=1; i<=${#@}; i++ )); do
      newPATH="${newPATH//:+(${@:${i}:1})*([^:])/}"     # s/:\/path[^:]*//g
   done
   newPATH="${newPATH#:}"      # remove leading colon
   newPATH="${newPATH%:}"      # remove trailing colon
   # disable extended globbing if it was enabled in this function
   [[ $extglobVar -eq 1 ]] && shopt -u extglob
   unset PATH 
   PATH="${newPATH}" 
   export PATH
   return 0 
} 

path_remove /opt/local/bin /usr/local/bin

path_remove_all /opt/local /usr/local 

0

পাথ_ম্রেভ_এল (প্রক্সি দিয়ে):

-newPATH="${newPATH//:+(${@:${i}:1})*([^:])/}" 
+newPATH="${newPATH//:${@:${i}:1}*([^:])/}"        # s/:\/path[^:]*//g 

0

যদিও এটি খুব পুরানো থ্রেড, আমি ভেবেছিলাম এই সমাধানটি আগ্রহী হতে পারে:

PATH="/usr/lib/ccache:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games"
REMOVE="ccache" # whole or part of a path :)
export PATH=$(IFS=':';p=($PATH);unset IFS;p=(${p[@]%%$REMOVE});IFS=':';echo "${p[*]}";unset IFS)
echo $PATH # outputs /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

এটি এই ব্লগ পোস্টে পাওয়া গেছে । আমি মনে করি আমি এটি সবচেয়ে পছন্দ করি :)


0

আমি এখানে বেশিরভাগ লোকের চেয়ে কিছুটা ভিন্ন পন্থা নিয়েছি এবং বিশেষভাবে কেবল স্ট্রিং ম্যানিপুলেশনে ফোকাস করেছি, যেমন:

path_remove () {
    if [[ ":$PATH:" == *":$1:"* ]]; then
        local dirs=":$PATH:"
        dirs=${dirs/:$1:/:}
        export PATH="$(__path_clean $dirs)"
    fi
}
__path_clean () {
    local dirs=${1%?}
    echo ${dirs#?}
}

উপরেরটি আমি ব্যবহার করি চূড়ান্ত ফাংশনগুলির একটি সরল উদাহরণ। আমিও তৈরি করেছি path_add_beforeএবং path_add_afterআপনি / সামনে একটি পাথ একটি নির্দিষ্ট পথ ইতিমধ্যে পাথ পরে সন্নিবেশ অনুমতি দেয়।

ফাংশন পূর্ণ সেট পাওয়া যায় path_helpers.sh আমার মধ্যে dotfiles । তারা PATH স্ট্রিংয়ের শুরু / মাঝামাঝি / শেষের দিকে সরানো / সংযোজন / প্রিপেন্ডিং / সন্নিবেশকে সম্পূর্ণ সমর্থন করে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.