শেলচেক বেসনাম ব্যবহার না করার পরামর্শ দিচ্ছে: কেন?


25

আমি বাইরে চেষ্টা করছি shellcheck

আমার এমন কিছু আছে

basename "${OPENSSL}" 

এবং আমি নিম্নলিখিত পরামর্শ পেতে

Use parameter expansion instead, such as ${var##*/}.

ব্যবহারিক দৃষ্টিকোণ থেকে আমি কোন পার্থক্য দেখতে পাচ্ছি

$ export OPENSSL=/opt/local/bin/openssl
$ basename ${OPENSSL}
openssl
$ echo ${OPENSSL##*/}
openssl

যেহেতু basenameরয়েছে POSIX চশমা , আমি একটি কারণ কেন এটিকে সেরা পন্থা হওয়া উচিত না। কোন ইঙ্গিত?


8
এটি যখন প্রয়োজন হয় না তখন এটি একটি নতুন প্রক্রিয়া কাঁটাচামচ করে।
জর্ডানম

@ জর্ডানম মোটামুটি ... আমি দক্ষতা নিয়ে ভাবি নি।
মাত্তেও

3
@ জর্ডানম অন্যদিকে এটি বাশ ছাড়াও শাঁস নিয়ে কাজ করে
মাত্তিও

1
@JosephR। এটাই আমি ভেবেছিলাম তবে সন্ধান পেয়েছি এটি কার্যকর হয় না csh। আমার ধারণা cshতখন পসিক্স নয়।
টেরডন

3
@terdon - csh পসিক্স থেকে খুব দূরে।
জর্ডানম

উত্তর:


25

এটি দক্ষতা সম্পর্কে নয় - এটি সঠিকতা সম্পর্কে। basenameপ্রিন্ট করা ফাইলের নামগুলি সীমিত করতে নিউলাইনগুলি ব্যবহার করে। সাধারণ ক্ষেত্রে যখন আপনি কেবল একটি ফাইল নাম পাস করেন, এটি এর আউটপুটে একটি পিছনে নতুন লাইন যুক্ত করে। যেহেতু ফাইলের নামগুলিতে নিজেরাই নিউলাইন থাকতে পারে তাই এই ফাইলগুলির নামগুলি সঠিকভাবে পরিচালনা করতে অসুবিধা হয়।

এটি আরও সত্য যে মানুষ সাধারণত ব্যবহার দ্বারা জটিল basenameভালো: "$(basename "$file")"। এটি জিনিসগুলিকে আরও বেশি কঠিন করে তোলে, কারণ এখান থেকে সমস্ত পেছনের নতুন লাইনগুলি $(command)স্ট্রিপ করে । একটি নতুন লাইন দিয়ে শেষ হয় এমন সম্ভাব্য কেসটি বিবেচনা করুন । তারপরে একটি অতিরিক্ত নিউলাইন যুক্ত হবে, তবে আপনাকে একটি ভুল ফাইল নাম রেখে নতুন দুটি লাইনই ছড়িয়ে দেবে।command$filebasename"$(basename "$file")"

এর সাথে আর একটি সমস্যা basenameহ'ল যদি $fileকোনও -(ড্যাশ ওরফে বিয়োগ) দিয়ে শুরু হয় , তবে এটি বিকল্প হিসাবে ব্যাখ্যা করা হবে। এই এক ঠিক করা সহজ:$(basename -- "$file")

ব্যবহারের শক্তিশালী উপায় basenameহ'ল:

# A file with three trailing newlines.
file=$'/tmp/evil\n\n\n'

# Add an 'x' so we can tell where $file's newlines end and basename's begin.
file_x="$(basename -- "$file"; printf x)"

# Strip off two trailing characters: the 'x' added by us and the newline added by basename. 
base="${file_x%??}"

একটি বিকল্প ব্যবহার করা হয় ${file##*/}, যা সহজ তবে এর নিজস্ব বাগ রয়েছে। বিশেষ করে, এটা ক্ষেত্রে যেখানে মধ্যে ভুল $fileহয় /বা foo/


2
খুব ভাল পয়েন্ট, +1। অপারেটরটি আমার পরিবর্তে এটি মেনে নিয়েছে।
টেরডন

2
কাউন্টারপয়েন্ট: যদি $fileহয় foo/? এটা যদি হয় /?
গিলস 'অশুভ হওয়া বন্ধ করুন'

2
@ গিলস: ঠিক বলেছেন। আমি ভাবতে শুরু করি যে basenameপদ্ধতির সর্বোপরি হ্যাকি যতটা ভাল। আমি যে সর্বোত্তম বিকল্পগুলি নিয়ে আসতে পারি তা হ'ল ${${${file}%%/#}##*/}এবং [[ $file =~ "([^/]*)/*$" ]] && printf "%s" $match[1]উভয়ই zsh- নির্দিষ্ট এবং কোনটিই /সঠিকভাবে পরিচালনা করে না।
ম্যাট

@ এটারডন ধন্যবাদ যে আপনি এটি ব্যক্তিগতভাবে নেন নি :-)। নিউলাইনযুক্ত ফাইলগুলি সাধারণ নয় তবে ম্যাটের একটি বিষয় রয়েছে। অবশ্যই ভেরিয়েবল বিকল্প ব্যবহার আরও কার্যকর more
মাত্তিও

16

shellcheckএর সোর্স কোডে সম্পর্কিত লাইনগুলি হ'ল :

checkNeedlessCommands (T_SimpleCommand id _ (w:_)) | w `isCommand` "dirname" =
    style id "Use parameter expansion instead, such as ${var%/*}."
checkNeedlessCommands (T_SimpleCommand id _ (w:_)) | w `isCommand` "basename" =
    style id "Use parameter expansion instead, such as ${var##*/}."
checkNeedlessCommands _ = return ()

পরিষ্কারভাবে কোনও ব্যাখ্যা দেওয়া হয়নি তবে ফাংশনটির নামের উপর ভিত্তি করে ( checkNeedlessCommands) দেখে মনে হচ্ছে @ জোর্ডানম বেশ সঠিক এবং এটি আপনাকে একটি নতুন প্রক্রিয়া জালিয়াতি এড়াতে পরামর্শ দিচ্ছে।


7
উত্সটি আপনার সাথে থাকতে পারে :)
জোসেফ আর।

3

dirname, basename, readlinkইত্যাদি (ধন্যবাদ @Marco - এই পরিস্থিতি সংশোধিত হয়) বহনযোগ্যতা সমস্যা তৈরি করতে পারেন কখন নিরাপত্তা গুরুত্বপূর্ণ হয়ে ওঠে (পথের নিরাপত্তা প্রয়োজন)। অনেক সিস্টেম (যেমন ফেডোরা লিনাক্স) এটিকে রাখে /binযেখানে অন্যরা (ম্যাক ওএসএক্সের মতো) এটিকে রাখে /usr/bin। তারপরে উইন্ডোজে ব্যাশ রয়েছে, যেমন সাইগউইন, এমএসএস এবং অন্যান্য। সম্ভব হলে খাঁটি বাশ থাকাই সর্বদা ভাল। (@ মার্কো মন্তব্য অনুসারে)

বিটিডাব্লু, শেলচেকের পয়েন্টারের জন্য ধন্যবাদ, আমি এর আগে দেখিনি।


1
1) "সুরক্ষা" বলতে কী বোঝ? তুমি কি বিস্তারিত বলতে পারো? 2) ওপি মোটেই উল্লেখ করে না dirname। 3) বেসিক কোর ইউটিলিটিগুলি যেখানেই সঞ্চিত থাকে তা প্যাথ-এ থাকা উচিত। আমি এখনও এমন কোনও সিস্টেম দেখিনি যেখানে basenameপ্যাথ-এ ছিল না। 4) ধরে নেওয়া বাশ উপলভ্য একটি উদ্বেগজনক সমস্যা। ব্যাশ থেকে দূরে থাকুন এবং পোর্টিব্যালিটির প্রয়োজন হলে পসিক্স শেল ব্যবহার করা সবসময় ভাল।
মার্কো

@ মার্কো এই বিষয়গুলি দেখানোর জন্য ধন্যবাদ। হ্যাঁ আপনি সঠিক যে ইউটিলিটিগুলি পথে রয়েছে। তবে যেখানে কেউ বাশ স্ক্রিপ্টে অতিরিক্ত সুরক্ষা সরবরাহ করতে চায়, সেখানে চূড়ান্ত পথ সরবরাহ করা ভাল অনুশীলন। সুতরাং '/ বিন / বেসনাম' কল করা রেডহ্যাট সিস্টেমগুলির জন্য কাজ করবে, তবে এটি একটি ম্যাকের মধ্যে একটি ত্রুটি তৈরি করবে। এটি বাশ কুকবুকে আরও ভালভাবে ব্যাখ্যা করা হয়েছে যেখানে pages০০ পৃষ্ঠার প্রায় এক চতুর্থাংশ এই বিষয়ে উত্সর্গীকৃত। আমরা আমাদের নিখরচায় উত্স সুরক্ষিত-lib- তে সুরক্ষার সমস্যাগুলি সমাধান করার জন্য মোটামুটি চেষ্টা করেছি ।
অসমল্যাব

@ মারকো পয়েন্ট 4 একটি বৈধ মন্তব্য তবে প্রশ্ন (ওপি) শুরু হয় এবং শেলচেকের চারপাশে লেখা হয়েছে যা উভয় sh / bash স্ক্রিপ্টগুলি পরীক্ষা করার জন্য ডিজাইন করা হয়েছে। সুতরাং আমাদের ধরে নিতে হবে এটি ডিফল্টভাবে কঠোরভাবে পিক্সিক্স নয়।
অসমল্যাব

@ মার্কো সুরক্ষার পথের পরিবেশের পরিবর্তনশীলটির সহজেই আপস করা যেতে পারে। উদাহরণস্বরূপ, আমি কয়েক বছর আগে এটি জানতে পেরে খুব অবাক হয়েছি যে স্থানীয়ভাবে ইনস্টল করা রুবি আরভিএম ডিফল্টরূপে এটি সিস্টেমের পথে আগে রেখেছিল।
AsymLabs

ওপি বিশেষত পসিক্সের উল্লেখ করেছে posixএবং প্রশ্নটি ট্যাগ হয়েছে এবং নেই bash। আমি কোনও সূচক খুঁজে পেতে ব্যর্থ হয়েছি যে ওপিতে ব্যাশ সমাধান দরকার। আপনার বক্তব্য "খাঁটি বাশ থাকাই সর্বদা ভাল" কেবল সরল ভুল, আমি দুঃখিত।
মার্কো
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.