@ কুসালানন্দ ইতিমধ্যে প্রাথমিক সমস্যা এবং এটি কীভাবে সমাধান করবেন সে সম্পর্কে ব্যাখ্যা করেছেন এবং @্লেইন জ্যাকম্যানের সাথে লিঙ্কযুক্ত বাশ FAQ এন্ট্রিও প্রচুর দরকারী তথ্য সরবরাহ করে। এই সংস্থানগুলির উপর নির্ভর করে আমার সমস্যার মধ্যে কী ঘটছে তার একটি বিশদ বিবরণ এখানে।
আমরা একটি ছোট স্ক্রিপ্ট ব্যবহার করব যা এর প্রতিটি আর্গুমেন্টকে আলাদা লাইনে প্রিন্ট করে জিনিসগুলি ( argtest.bash
):
#!/bin/bash
for var in "$@"
do
echo "$var"
done
"ম্যানুয়ালি" পাস করার বিকল্পগুলি:
$ ./argtest.bash -rnv --exclude='.*'
-rnv
--exclude=.*
প্রত্যাশিত হিসাবে, অংশগুলি -rnv
এবং --exclude='.*'
দুটি আর্গুমেন্টে বিভক্ত হয়ে গেছে, কারণ এগুলি অকেজো হোয়াইটস্পেস (এটিকে শব্দ বিভাজন বলা হয় ) দ্বারা পৃথক করা হয় ।
আরও মনে রাখবেন যে চারপাশের উদ্ধৃতিগুলি .*
সরিয়ে ফেলা হয়েছে: একক উদ্ধৃতি শেলকে বিশেষ বিষয়বস্তু ছাড়াই তাদের বিষয়বস্তুগুলি পাস করতে বলে , কিন্তু উদ্ধৃতিগুলি কমান্ডের কাছে দেওয়া হয় না ।
যদি আমরা এখন স্ট্রিং হিসাবে একটি ভেরিয়েবলের বিকল্পগুলি (অ্যারে ব্যবহারের বিপরীতে) সংরক্ষণ করি, তবে উদ্ধৃতিগুলি সরানো হবে না :
$ OPTS="--exclude='.*'"
$ ./argtest.bash $OPTS
--exclude='.*'
এটি দুটি কারণে হয়: $OPTS
একক উদ্ধৃতিগুলির বিশেষ চিকিত্সা রোধ করার সময় ডাবল কোটগুলি ব্যবহৃত হয় , সুতরাং পরবর্তীগুলি মানটির অংশ:
$ echo $OPTS
--exclude='.*'
যখন এখন আমরা $OPTS
কোনও কমান্ডের যুক্তি হিসাবে ব্যবহার করি তখন পরামিতি প্রসারণের আগে উদ্ধৃতিগুলি প্রক্রিয়া করা হয় , সুতরাং উদ্ধৃতিগুলি $OPTS
"খুব দেরী" হয়।
এর অর্থ হ'ল (আমার মূল সমস্যাটিতে) rsync
প্যাটার্নের '.*'
পরিবর্তে বাদ দেওয়া প্যাটার্ন (কোটস সহ!) ব্যবহার করে .*
- এটি এমন ফাইলগুলিকে বাদ দেয় যার নামটি একটি বিন্দুতে অনুসরণ করে একক উদ্ধৃতি দিয়ে শুরু হয় এবং একক উদ্ধৃতি দিয়ে শেষ হয়। স্পষ্টতই এটি উদ্দেশ্য ছিল না।
সংজ্ঞা দেওয়ার সময় ডাবল উদ্ধৃতিগুলি বাদ দিতে একটি কর্মক্ষেত্রটি হত $OPTS
:
$ OPTS2=--exclude='.*'
$ ./argtest.bash $OPTS2
--exclude=.*
যাইহোক, আরও জটিল ক্ষেত্রে সূক্ষ্ম পার্থক্যের কারণে সর্বদা পরিবর্তনশীল অ্যাসাইনমেন্টগুলি উদ্ধৃত করা একটি ভাল অনুশীলন ।
@ কুসালানন্দ যেমন উল্লেখ করেছেন, উদ্ধৃতি না দেওয়াও .*
কাজ করতে পারত। প্যাটার্নের প্রসারণ রোধ করতে আমি উদ্ধৃতিগুলি যোগ করেছি , তবে এই বিশেষ ক্ষেত্রে এটি কঠোরভাবে প্রয়োজন ছিল না :
$ ./argtest.bash --exclude=.*
--exclude=.*
এটি সক্রিয় আউট ব্যাশ যে করে প্যাটার্ন সম্প্রসারণ সঞ্চালন কিন্তু প্যাটার্ন --exclude=.*
যেকোনো ফাইল মিলছে না, তাই প্যাটার্ন কমান্ড কাছে হস্তান্তর করা হয়। তুলনা করা:
$ touch some_file
$ ./argtest.bash some_*
some_file
$ ./argtest.bash does_not_exit_*
does_not_exit_*
তবে, প্যাটার্নটি উদ্ধৃত না করা বিপজ্জনক, কারণ যদি (যে কোনও কারণে) কোনও ফাইলের মিল ছিল --exclude=.*
তবে প্যাটার্নটি প্রসারিত হবে:
$ touch -- --exclude=.special-filenames-happen
$ ./argtest.bash --exclude=.*
--exclude=.special-filenames-happen
অবশেষে, আসুন দেখুন কেন অ্যারে ব্যবহার করা আমার উদ্ধৃতি সমস্যাটিকে বাধা দেয় (কমান্ড আর্গুমেন্টগুলি সঞ্চয় করতে অ্যারে ব্যবহারের অন্যান্য সুবিধার পাশাপাশি)।
অ্যারের সংজ্ঞা দেওয়ার সময়, শব্দ বিভাজন এবং উদ্ধৃতি হ্যান্ডলিং প্রত্যাশা অনুযায়ী ঘটে:
$ ARRAY_OPTS=( -rnv --exclude='.*' )
$ echo length of the array: "${#ARRAY_OPTS[@]}"
length of the array: 2
$ echo first element: "${ARRAY_OPTS[0]}"
first element: -rnv
$ echo second element: "${ARRAY_OPTS[1]}"
second element: --exclude=.*
কমান্ডটিতে বিকল্পগুলি পাস করার সময়, আমরা সিনট্যাক্সটি ব্যবহার করি "${ARRAY[@]}"
, যা অ্যারের প্রতিটি উপাদানকে পৃথক শব্দে প্রসারিত করে:
$ ./argtest.bash "${ARRAY_OPTS[@]}"
-rnv
--exclude=.*