Command (কমান্ড $ আরগ) উদ্ধৃত করার সঠিক উপায় কী?


17

এই ধাঁধাটি সমাধান করার এখন সময় এসেছে যা বছরের পর বছর ধরে আমাকে বিরক্ত করছে ...

আমি এটি সময়ে সময়ে মিলিত হয়েছি এবং ভেবেছিলাম এটিই যাওয়ার উপায়:

$(comm "$(arg)")

এবং ভেবেছিলাম আমার মতামত অভিজ্ঞতার দ্বারা দৃ strongly়ভাবে সমর্থিত। তবে আমি আর নিশ্চিত নই। শেলচেকও তার মন তৈরি করতে পারে না। এটি উভয়:

"$(dirname $0)"/stop.bash
           ^-- SC2086: Double quote to prevent globbing and word splitting.

এবং:

$(dirname "$0")/stop.bash
^-- SC2046: Quote this to prevent word splitting.

পিছনে যুক্তি কি?

(এটি শেলচেক সংস্করণ 0.4.4, বিটিডাব্লু।)


1
সমস্ত প্রতিস্থাপন উদ্ধৃতি।
Ignacio Vazquez-Abram 18

3
শুধু এই মত: "$(dirname "$0")"/stop.bash? মনে হচ্ছে কাজ করছে ... গল্পটা কী?
টমাসজ

1
প্রসঙ্গটি কখন পরিবর্তিত হয়েছে তা জানতে ব্যাশ যথেষ্ট স্মার্ট।
Ignacio Vazquez-Abram 18

1
এটি সম্পর্কে এটি ভাবুন shell_level_1 $(shell_level_2) shell_level_1:: আপনি যখন $(....)শেলের একটি "সাবলেভিল" প্রবেশ করান, তবে আপনি এটিতে লিখতে পারবেন যেন আপনি প্রাথমিক স্তরে ছিলেন (যেমন, আপনি সরাসরি , এর "পরিবর্তে সরাসরি লিখতে পারেন \")। যেমন: touch "/tmp/a file" ; echo "its size is: $(find "/tmp/a file" -ls | awk '{print $5}) ..." : if you used backticks you'd have to সন্ধান করুন / "/ টিএমপি / একটি ফাইল \" `এবং print \$5। সঙ্গে $(...)কোন প্রয়োজন: নতুন স্তর শেল আত্তীকরণ করে এবং আপনি সরাসরি লিখতে পারেন যেমন যদি আপনার ব্যাখ্যাকারী এখন খুব যে পর্যায়ে রয়েছে।
অলিভিয়ার ডুলাক 16'18

"শেলচেকও তার মন তৈরি করতে পারে না।" - দুটি রানের বিভিন্ন জায়গায় দুটি পৃথক বার্তা এবং পয়েন্ট রয়েছে। এটা উভয় চায়।
ইজকাটা

উত্তর:


45

আপনার ব্যবহার করা দরকার "$(somecmd "$file")"

উদ্ধৃতিগুলি ব্যতীত, একটি স্থান সহ একটি পাথ যুক্তি অনুসারে বিভক্ত somecmdহবে এবং এটি ভুল ফাইলটিকে লক্ষ্যবস্তু করবে। সুতরাং আপনার অভ্যন্তরের উদ্ধৃতিগুলি দরকার।

এর আউটপুটে থাকা কোনও ফাঁকা somecmdস্থানও বিভাজন ঘটায়, সুতরাং আপনার পুরো কমান্ডের বিকল্পের বাইরের কোট দরকার।

কমান্ড সাবস্টিটিউশনের অভ্যন্তরের উদ্ধৃতিগুলির বাইরের উদ্ধৃতিগুলির কোনও প্রভাব নেই। বাশের নিজস্ব রেফারেন্স ম্যানুয়ালটি এ সম্পর্কে খুব পরিষ্কার নয়, তবে বাশগাইড স্পষ্টভাবে এটি উল্লেখ করেছেPOSIX টেক্সট এছাড়াও এটি প্রয়োজন, যেমন "কোনো বৈধ শেল স্ক্রিপ্ট" ভিতরে অনুমতি দেওয়া হয় $(...):

সঙ্গে $(command)ফর্ম, ম্যাচিং সমাপনী প্রথম বন্ধনী খোলা প্রথম বন্ধনী নিম্নলিখিত সমস্ত অক্ষর কমান্ড গঠন করে। কোনও বৈধ শেল স্ক্রিপ্ট কমান্ডের জন্য ব্যবহার করা যেতে পারে, কেবলমাত্র পুনর্নির্দেশের সমন্বিত স্ক্রিপ্ট ছাড়া যা অনির্দিষ্ট ফলাফল দেয় produces


উদাহরণ:

$ file="./space here/foo"

ক। কোনও উদ্ধৃতি নেই, dirnameউভয়ই প্রক্রিয়া করে ./spaceএবং here/foo:

$ printf "<%s>\n" $(dirname $file)
<.>
<here>

খ। ভিতরে উদ্ধৃতি, dirnameপ্রক্রিয়া ./space here/foo, প্রদান ./space here, যা দুটি বিভক্ত:

$ printf "<%s>\n" $(dirname "$file")
<./space>
<here>

গ। বাইরের উক্তি, dirnameউভয় প্রসেস করে ./spaceএবং here/fooপৃথক লাইনে আউটপুট দেয় তবে এখন দুটি রেখা একক যুক্তি গঠন করে :

$ printf "<%s>\n" "$(dirname $file)"
<.
here>

ঘ। ভিতরে এবং বাইরে উভয়ই উদ্ধৃতি, এটি সঠিক উত্তর দেয়:

$ printf "<%s>\n" "$(dirname "$file")"
<./space here>

(এটি সম্ভবত dirnameপ্রথম যুক্তি প্রক্রিয়াকৃত হলে সহজতর হত , তবে এটি কে এবং সি এর মধ্যে পার্থক্য প্রদর্শন করবে না))

দ্রষ্টব্য যে dirname(এবং সম্ভবত অন্যদের) --সাথে আপনারও যোগ করা দরকার , ফাইলের নামটি কোনও ড্যাশ দিয়ে শুরু হওয়ার ক্ষেত্রে বিকল্প হিসাবে নেওয়া থেকে রোধ করতে, তাই ব্যবহার করুন "$(dirname -- "$file")"


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