উত্তর:
সেটিং করার সময় উদ্ধৃতি দেওয়া $FOO
যথেষ্ট নয়। আপনার পরিবর্তনশীল রেফারেন্সটিও উদ্ধৃত করতে হবে:
me$ FOO="BAR * BAR"
me$ echo "$FOO"
BAR * BAR
সংক্ষিপ্ত উত্তর
অন্যরা যেমন বলেছে - অদ্ভুত আচরণ রোধ করতে আপনার সর্বদা চলকগুলি উদ্ধৃত করা উচিত। সুতরাং শুধু প্রতিধ্বনি instead foo এর পরিবর্তে প্রতিধ্বনি "। Foo" ব্যবহার করুন ।
দীর্ঘ উত্তর
আমি মনে করি যে এই উদাহরণটি আরও ব্যাখ্যা দেয় কারণ এটির চেহারার চেয়ে বেশি দেখা যাচ্ছে more
আমি দেখতে পাচ্ছি কোথায় আপনার বিভ্রান্তি আসে কারণ আপনি নিজের প্রথম উদাহরণটি চালানোর পরে আপনি সম্ভবত নিজেকে ভেবেছিলেন যে শেলটি অবশ্যই করছে:
সুতরাং আপনার প্রথম উদাহরণ থেকে:
me$ FOO="BAR * BAR"
me$ echo $FOO
প্যারামিটার সম্প্রসারণের পরে সমান:
me$ echo BAR * BAR
এবং ফাইলের নাম সম্প্রসারণ সমান:
me$ echo BAR file1 file2 file3 file4 BAR
এবং আপনি যদি কেবল echo BAR * BAR
কমান্ড লাইনে টাইপ করেন তবে দেখতে পাবেন যে সেগুলি সমান।
সুতরাং আপনি সম্ভবত নিজেকে ভেবেছিলেন "আমি যদি * এড়িয়ে চলি তবে আমি ফাইলের নামটি বাড়াতে পারি"
সুতরাং আপনার দ্বিতীয় উদাহরণ থেকে:
me$ FOO="BAR \* BAR"
me$ echo $FOO
প্যারামিটার সম্প্রসারণের পরে সমতুল্য হওয়া উচিত:
me$ echo BAR \* BAR
এবং ফাইলের নাম সম্প্রসারণের সমতুল্য হওয়া উচিত:
me$ echo BAR \* BAR
এবং যদি আপনি কমান্ড লাইনে সরাসরি "প্রতিধ্বনি বার * * বার" টাইপ করার চেষ্টা করেন তবে এটি অবশ্যই "বার * বার" মুদ্রণ করবে কারণ ফাইলের নাম প্রসারিত হওয়ার ফলে বাধা দেওয়া হয়েছিল।
তাহলে $ foo ব্যবহার করা কেন কাজ করে না?
এটি ঘটে কারণ সেখানে তৃতীয় সম্প্রসারণ ঘটে যা উদ্ধৃতি অপসারণ। বাশ ম্যানুয়াল থেকে উদ্ধৃতিটি হ'ল:
পূর্ববর্তী প্রসারণের পরে, 'of', '' ', এবং' "'অক্ষরের সমস্ত অনুচ্চারিত ঘটনাগুলি উপরের বিস্তারের কোনওটি থেকে সরানো হয়নি।
সুতরাং যা ঘটে যখন আপনি কমান্ড লাইনে সরাসরি কমান্ডটি টাইপ করেন, পালানোর চরিত্রটি কোনও পূর্ববর্তী প্রসারণের ফলাফল নয় তাই BASH এটি প্রতিধ্বনি কমান্ডে প্রেরণের আগে এটি সরিয়ে দেয়, তবে দ্বিতীয় উদাহরণে "" * "ছিল পূর্ববর্তী প্যারামিটার বিস্তারের ফলাফল, সুতরাং এটি সরানো হয়নি। ফলস্বরূপ, প্রতিধ্বনি "\ *" পান এবং এটি এটি প্রিন্ট করে।
প্রথম উদাহরণের মধ্যে পার্থক্যটি লক্ষ্য করুন - "*" এমন অক্ষরগুলির অন্তর্ভুক্ত নয় যা উদ্ধৃতি অপসারণ দ্বারা সরানো হবে।
আশা করি এটা বোধ গম্য। শেষে একই উপসংহার - কেবল উদ্ধৃতি ব্যবহার করুন। আমি কেবল ভেবেছিলাম যে আমি কীভাবে পালাতে হবে তা ব্যাখ্যা করব, যা কেবলমাত্র পরামিতি এবং ফাইলনামের সম্প্রসারণ খেলতে না পারলে যৌক্তিকভাবে কাজ করা উচিত।
বেস বিস্তারের সম্পূর্ণ ব্যাখ্যার জন্য, দেখুন:
http://www.gnu.org/software/bash/manual/bashref.html#Shell-Expansions
আমি এই পুরানো থ্রেডে কিছুটা যুক্ত করব।
সাধারণত আপনি ব্যবহার করবেন
$ echo "$FOO"
তবে এই সিনট্যাক্স নিয়েও আমার সমস্যা হয়েছিল। নিম্নলিখিত স্ক্রিপ্ট বিবেচনা করুন।
#!/bin/bash
curl_opts="-s --noproxy * -O"
curl $curl_opts "$1"
*
চাহিদা ধারণকৃত পাস করা curl
, কিন্তু একই সমস্যা দেখা দেয় হবে। উপরের উদাহরণটি কাজ করবে না (এটি বর্তমান ডিরেক্টরিতে ফাইলের নামগুলিতে প্রসারিত হবে) এবং তাও করবে না \*
। আপনি উদ্ধৃতিও দিতে পারেন না $curl_opts
কারণ এটিতে একটি একক (অবৈধ) বিকল্প হিসাবে স্বীকৃত হবে curl
।
curl: option -s --noproxy * -O: is unknown
curl: try 'curl --help' or 'curl --manual' for more information
অতএব আমি বিশ্বব্যাপী প্যাটার্নে প্রয়োগ করা হয় বা বিল্ট-ইন পতাকা ব্যবহার করে পুরোপুরিভাবে ফাইলের নাম রোধ করতে bash
ভেরিয়েবলের ব্যবহারের পরামর্শ দেব ।$GLOBIGNORE
set -f
#!/bin/bash
GLOBIGNORE="*"
curl_opts="-s --noproxy * -O"
curl $curl_opts "$1" ## no filename expansion
আপনার মূল উদাহরণ প্রয়োগ করা:
me$ FOO="BAR * BAR"
me$ echo $FOO
BAR file1 file2 file3 file4 BAR
me$ set -f
me$ echo $FOO
BAR * BAR
me$ set +f
me$ GLOBIGNORE=*
me$ echo $FOO
BAR * BAR
SELECT * FROM etc.
এটিই একমাত্র উপায়।
echo "$FOO"
এটি printf
বরং echo
কমান্ড লাইনে ব্যবহার করার অভ্যাসে প্রবেশের উপযুক্ত হতে পারে ।
এই উদাহরণে এটি খুব বেশি সুবিধা দেয় না তবে আরও জটিল আউটপুট সহ এটি আরও কার্যকর হতে পারে।
FOO="BAR * BAR"
printf %s "$FOO"