আমি কীভাবে অসমর্থিত 'শপট' বিকল্পগুলিকে আমার .bashrc এ ত্রুটি সৃষ্টি হতে আটকাতে পারি?


9

আমি তুলনামূলক ভিন্ন ভিন্ন পরিবেশে কাজ করি যেখানে আমি বিভিন্ন এইচপিসি নোড, ভিএম, বা আমার ব্যক্তিগত ওয়ার্কস্টেশনগুলিতে বাশের বিভিন্ন সংস্করণ চালাচ্ছি। যেহেতু আমি আমার লগইন স্ক্রিপ্টগুলি একটি গিট রেপোতে রেখেছি, আমি .bashrcবোর্ড "জুড়ে" (যদি এই হোস্টটি, তবে ... "- টাইপ মেসেসি ছাড়াই বোর্ড জুড়ে একই (ইশ) ব্যবহার করতে চাই ।

আমি বাশ the 4.1 এর ডিফল্ট আচরণ পছন্দ করি যা কী টিপানোর সময় প্রসারিত cd $SOMEPATHহয় । 4.2 বা ততোধিক বাশিতে আপনাকে এই আচরণটি পুনরায় সক্ষম করতে হবে এবং এটি 4.2.29 অবধি উপলব্ধ হবে না । যদিও এটি কেবল একটি উদাহরণ; অন্যটি, সম্ভবত সম্পর্কিত বিকল্প, (যদিও এটি ঠিক কী তা আমি জানি না ) এছাড়াও v4.2 এ ডিফল্ট আচরণ পরিবর্তন করতে পারে।cd /the/actual/pathTabshopt -s direxpandshoptcomplete_fullquote

যাইহোক, direxpandব্যাশ 'র পূর্ববর্তী সংস্করণে দ্বারা স্বীকৃত হয় না, এবং যদি আমি চেষ্টা shopt -s direxpandআমার মধ্যে .bashrc, এটি একটি ত্রুটি বার্তায় ফলাফল কনসোলে প্রত্যেক সময় আমি একটি পুরোনো ব্যাশ সঙ্গে একটি নোড লগ ইন ছাপা হচ্ছে:

-bash: shopt: direxpand: invalid shell option name

আমি যা করতে চাই তা হল shop -s direxpandবাশ> ৪.১ এ শক্তিশালী উপায়ে বিকল্পটি সক্ষম করতে শর্তসাপেক্ষে প্রায় আবৃত করা, বাশের পুরানো সংস্করণগুলিকে ছাওয়া না করে ( যেমন , কেবল ত্রুটির আউটপুটটিকে পুনর্নির্দেশ নয় /dev/null)।


আমার উত্তর কীভাবে কাজে লাগেনি?
লুসিয়ানো এন্ড্রেস মার্টিনি

@ লুসিওআনড্রেসমার্টিনি এটি করেছে, এবং এটি সমাধানটি আমি নিজের সাথে শেষ করেছিলাম .bashrc। আমি এখনও $BASH_VERSINFOআমার নিজের উত্সাহের জন্য চলমান শেলের বড় / গৌণ সংস্করণটি জিজ্ঞাসাবাদ করতে কীভাবে ব্যবহার করব তার একটি রেকর্ড চেয়েছিলাম , এজন্য আমি নিজের উত্তর পোস্ট করা শেষ করেছি। :)
TheDudeAbides

আমার উত্তরে দেখুন আমার শেল স্ক্রিপ্টের সাথে প্রোগ্রামগুলির সংস্করণটির তুলনা করার বিষয়ে কিছু আছে।
লুসিয়ানো অ্যান্ড্রেস মার্টিনি

উত্তর:


14

direxpandএর আউটপুটে উপস্থিত রয়েছে কিনা তা পরীক্ষা করে দেখুন shoptএবং এটি সক্ষম করুন:

shopt | grep -q '^direxpand\b' && shopt -s direxpand

4
আরও ভাল করে নিন যে grep -q '^direxpand\b'ক্ষেত্রে কোনও ভবিষ্যতের সংস্করণ বা ব্যাশের কাঁটাচামড়ার একটি বিকল্প রয়েছে যা এটিকে একটি স্ট্রিং হিসাবে রয়েছে এবং মুছে ফেলে direxpand। এই সুনির্দিষ্ট ক্ষেত্রে অসম্ভব, তবে এটি দৃ cost় হতে খুব বেশি খরচ হয় না।
গিলস 'অসন্তুষ্ট হওয়া বন্ধ করুন'

ধন্যবাদ লুসিও। আমি আমার নিজের প্রশ্নের উত্তর দেওয়ার ইচ্ছা করেছি, তবে আমার সম্পাদনাগুলি পিয়ার পর্যালোচনার পরে আমি আপনার উত্তরটি গ্রহণ করব Maybe সম্ভবত আপনি এগুলি নিজেই অনুমোদন করতে পারেন?
TheDudeAbides

4
বাশ নির্দিষ্ট শেল বিকল্পগুলি জিজ্ঞাসা করতে অনুমতি দেয়, যাতে কেউ ব্যবহার করতে পারে [ -z "$(shopt -po direxpand 2>&-)" ] || shopt -s direxpand। রিজেক্স সমস্যা আর নেই! :-)
ডেভিড ফোরস্টার

@ ডেভিডফোস্টার আমি যুক্তিটি ঘুরিয়ে দেব: [ -n "blah" ] && shopt blahআপনি যেভাবে শব্দটি উচ্চারণ করেছেন, আপনি বলছেন "যদি ডাইরেক্টস্প্যান্ড অসমর্থিত হয়, তবে এই জিনিসটি করবেন না"।
ধনী

1
@ রিচ: আমার বেশিরভাগ শেল স্ক্রিপ্টগুলির set -eশীর্ষে অন্তর্ভুক্ত রয়েছে , তাই আমি প্রায় এইভাবে শর্ট-কাট যুক্তি ব্যবহার করার ঝোঁক।
ডেভিড ফোরস্টার

16

ত্রুটিগুলি পুনর্নির্দেশের সাথে কী হয়েছে তা আমি দেখতে পাচ্ছি না /dev/null। আপনি যদি নিজের কোডটি set -eদৃust় হতে চান তবে সাধারণ প্রতিমাটি ব্যবহার করুন … || true:

shopt -s direxpand 2>/dev/null || true

বিকল্পটি না থাকলে আপনি যদি কিছু ফ্যালব্যাক কোড চালনা করতে চান তবে এর রিটার্নের স্থিতিটি ব্যবহার করুন shopt:

if shopt -s direxpand 2>/dev/null; then
   # the direxpand option exists
else
   # the direxpand option does not exist
fi

তবে আপনি যদি ত্রুটিটিকে দূরে সরানো সত্যিই অপছন্দ করেন তবে আপনি অন্তর্মুখী সম্পাদন করতে সমাপ্তির প্রক্রিয়াটি ব্যবহার করতে পারেন। এটি ধরে নিয়েছে যে আপনার কাছে বাশ ≤ 2.03 এর সাথে পুরানো মেশিন নেই যা প্রোগ্রামেবল সমাপ্তি নেই।

shopt_exists () {
  compgen -A shopt -X \!"$1" "$1" >/dev/null
}
if shopt_exists direxpand; then
  shopt -s direxpand
fi

এই পদ্ধতিটি কাঁটাচামচ এড়ায়, যা সাইগউইনের মতো কিছু পরিবেশে ধীর। সোজা করে তোলে 2>/dev/null, আমি মনে করি না আপনি পারফরম্যান্সের ক্ষেত্রে এটি পরাজিত করতে পারেন।


আমার মস্তিষ্ক যে যেখানে যেতে হবে তা নয় , তবে আমি compgenপ্রস্তাবটি পছন্দ করি । ওখানেই ভার্সিটি লেভেলের স্টাফ! পুনঃনির্দেশ এড়ানো /dev/nullকেবল একটি ব্যক্তিগত পছন্দ। আমি ক্ষমার পরিবর্তে অনুমতি চাইতে চাই, যদি তা বোঝা যায়? :)
TheDudeAbides

বাশ প্রোগ্রামযোগ্য সমাপ্তিতে সম্পূর্ণ অপ্রত্যাশিত বিদ্যালয়ের জন্য +1, যা আমাকে কী compgen -A shopt -X ...বোঝাতে চেয়েছিল তা বোঝাতে ম্যানুয়ালটিতে যেতে বাধ্য করেছিল forced
TheDudeAbides

4
@ দ্য ডুডঅ্যাবাইডস আমি ইউনিক্স এবং লিনাক্সেcompgen এইভাবে ব্যবহার সম্পর্কে পড়লাম , আমি জানি না যে এটি প্রথম প্রস্তাব করেছিল। (প্রোগ্রামটি শেষ হওয়ার আগে বাশকে আমার প্রধান শেল হিসাবে ব্যবহার করা বন্ধ করে দিয়েছি)) প্রোগ্রামিংয়ে সাধারণত অনুমতি চাওয়া খারাপ ধারণা there's কারণ কোনও কোডিংয়ের কারণে অনুমতি চেক আপনি আসলে যা করছেন তার সাথে মিলবে না এমন ঝুঁকি রয়েছে there's ত্রুটি (যেখানে আপনি যা যা পরীক্ষা করছেন তা আপনি যাচাই করছেন না) বা আপনি যা যা পরীক্ষা করেছেন তা ব্যবহার করার আগেই এটি পরিবর্তন হয়েছে
গিলস 'অশুভ হওয়া বন্ধ করুন'

5

আপনি যখন নিশ্চিতরূপে জানেন যে বাশের কোনও নির্দিষ্ট মেজর / গৌণ / প্যাচ রিলিজে একটি নির্দিষ্ট shoptবিকল্প উপলব্ধ রয়েছে তখন আপনি শর্তসাপেক্ষে এটি সক্ষম করার জন্য $BASH_VERSIONভেরিয়েবল বা $BASH_VERSINFO[]অ্যারের উপাদানগুলি পরীক্ষা করতে পারেন ।

এখানে 4.2.29 বা তার বেশি বাশের জন্য একটি পরীক্ষা রয়েছে, সংস্করণটি যেখানে direxpand প্রথম 4.2 সিরিজের সাথে পরিচয় হয়েছিল :

if [[ $BASH_VERSION == 4.2.* && ${BASH_VERSINFO[2]} -ge 29 ]] ||
   [[ ${BASH_VERSINFO[0]} -eq 4 && ${BASH_VERSINFO[1]} -ge 3 ]] ||
   [[ ${BASH_VERSINFO[0]} -ge 5 ]]; then
    shopt -s direxpand
fi

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

উল্লেখ্য ধনুর্বন্ধনী প্রায় , যা হয় প্রয়োজনীয়, এবং ব্যবহার এবং , যা পূর্ণসংখ্যা (স্থানীয়ের নির্ভরশীল) আভিধানিক তুলনা বদলে না। যদি উদ্ধৃত না হয় তবে অপারেটরের আরএইচএসকে বাশ / শর্তসীমার মধ্যে "এক্সটগ্লোব" নিদর্শন হিসাবে বিবেচনা করা হবে , যেমন এখানে উল্লেখ করা হয়েছে , যা আইজেওর সাথে তুলনামূলক তুলনায় আরও নান্দনিক "শুরু" করে তোলে।${BASH_VERSINFO[index]}-eq-gt==[[]]

$BASH_VERSINFOঅ্যারে সব তথ্য আপনি আউটপুট মধ্যে দেখতে চাই রয়েছে bash --version:

bash --version | head -1
# result:
# GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)

declare -p BASH_VERSINFO
# result:
# declare -ar BASH_VERSINFO='([0]="4" [1]="3" [2]="48" [3]="1" [4]="release" [5]="x86_64-pc-linux-gnu")'

বাশ সংস্করণ (গুলি) যার সাহায্যে বা তাদের আচরণ পরিবর্তন করেছে সেই ডকুমেন্টেশন থেকে যখন এটি স্পষ্ট হয় নাshopt , লুসিয়ানো প্রস্তাবিত পদ্ধতিটি ভাল:

# note the '-q' so that the matched pattern isn't actually printed
shopt | grep -q direxpand && shopt -s direxpand

... যেমন গিলস কেবল ত্রুটি ( shopt -s direxpand 2>/dev/null) উপেক্ষা করে এবং সম্ভবত $?একেবারে প্রয়োজনীয় কিনা তা যাচাইয়ের প্রস্তাব দেওয়া সমাধান ।

তথ্যসূত্র: 1 , 2 , 3
সম্পর্কিত পাঠ: সেট এবং শপট - দুটি কেন?


আপনি পছন্দ করতে কিছু ব্যবহার করতে সক্ষম হতে পারেন if [[ $BASH_VERSION > 4.3 ]];(যা মিলে যায় 4.3.0, 5.0ইত্যাদি, কিন্তু 4.3.0-alphaআমি জানি না যদি পরে আসলে গুরুত্বপূর্ণ।।)
ilkkachu

হাই @ilkkachu। বাশ v5.x কভার করার জন্য আপনার সম্পাদনার জন্য ধন্যবাদ। direxpandবিকল্প, যদিও ব্যাশ 4.2 সত্যিই পাওয়া যায়; আমি v4.2.53 এ একটি ডকার ইমেজ দিয়ে এটি চালিয়ে যাচাই করেছি docker run --rm bash:4.2 bash -c shopt | grep direxpand(এবং, ভাল পরিমাপের জন্য, এটি চালানো দ্বারা সত্যই v4.1.17 এ পাওয়া যায় নাdocker run --rm bash:4.1 bash -c shopt | grep direxpand )।
দ্য ডুডঅ্যাবাইডস

আহ ঠিক আছে, আমি পরীক্ষা করেছি 4.2.0এবং হোঁচট খেয়েছি যে এটি সেখানে কাজ করে না। পরিবর্তণের উল্লেখ এটা যোগ bash-4.3-alpha। আমি তখন মনে করি যে ${BASH_VERSINFO[2]}এটি সম্পর্কে সঠিক হওয়ার জন্য একজনের চেক করা দরকার , তবে আমি জানি না কোন পয়েন্ট রিলিজ এটি যুক্ত করেছে ...
ilkkachu

আমি মনে করি আমরা গিলস উপরের পয়েন্টটি মূলত প্রমাণ করেছি; প্রকৃতপক্ষে শেল বিকল্পটি সক্ষম করার চেষ্টা করা আরও ভাল এবং তারপরে এটি সমর্থন না করা হলে ত্রুটিটি মোকাবেলা করুন (বা এটি দমন করুন)।
দ্য ডুডইবাইডস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.