macOS-এ একটি শেল স্ক্রিপ্টে স্পেসযুক্ত ফাইলের নাম পাস করতে, স্ক্রিপ্টটি চালানোর সময় পাথটিকে একটি একক আর্গুমেন্ট হিসেবে উদ্ধৃতি চিহ্নে (কোট) রাখুন, তারপর স্ক্রিপ্টের ভেতরে "$1" ব্যবহার করুন। উদাহরণস্বরূপ, ./process-file.sh "/Users/sam/Documents/Quarterly Report.pdf" একটি ফাইলের নাম পাস করে; উদ্ধৃতি চিহ্ন ছাড়া শেল এটিকে একাধিক আর্গুমেন্টে বিভক্ত করে। সঠিকভাবে উদ্ধৃতি চিহ্নে রাখলে এই পদ্ধতিটি শেলের জন্য সংবেদনশীল অন্যান্য অক্ষরযুক্ত পাথের ক্ষেত্রেও কাজ করে।
পাথটিকে একটি আর্গুমেন্ট হিসেবে রেখে স্ক্রিপ্ট চালান
টার্মিনালে, ডিরেক্টরি সহ সম্পূর্ণ ফাইলের নাম বা পাথের চারপাশে ডাবল কোটেশন চিহ্ন দিন এবং স্ক্রিপ্টের নামটি আলাদা রাখুন:
./process-file.sh "/Users/sam/Documents/Quarterly Report.pdf"
সাধারণভাবে টাইপ করা পাথের জন্য প্রতিটি স্পেসের আগে একটি ব্যাকস্ল্যাশও কাজ করে: ./process-file.sh /Users/sam/Documents/Quarterly\ Report.pdf। পুরো পাথটিকে উদ্ধৃতি চিহ্নে রাখা পড়তে সহজ এবং এতে ভুলের সম্ভাবনা কম থাকে, বিশেষ করে যখন এতে একাধিক স্পেস থাকে। কোটেশন হলো শেলের সিনট্যাক্স; এগুলো পাথটিকে একটি একক আর্গুমেন্টে দলভুক্ত করে এবং স্ক্রিপ্টের প্রাপ্ত ফাইলের নামের অংশ হয় না। শেল সম্প্রসারণের (expansion) পরে ওয়ার্ড স্প্লিটিং (শব্দ বিভাজন) করে, তাই উদ্ধৃতি চিহ্নহীন পাথ স্পেসগুলোতে বিভক্ত হতে পারে। Bash Reference Manual: Quoting
ফাইলটি বর্তমান ডিরেক্টরিতে থাকলে, একটি আপেক্ষিক পাথও (relative path) কাজ করবে:
./process-file.sh "Quarterly Report.pdf"
আপনি যে ডিরেক্টরি থেকে কমান্ডটি চালাচ্ছেন সেখান থেকে পাথটিকে অবশ্যই একটি বিদ্যমান ফাইলের দিকে নির্দেশ করতে হবে। স্ক্রিপ্টটি নিজে এক্সিকিউটেবল না হলে, সেটিকে শেল দিয়ে কল করুন, উদাহরণস্বরূপ bash process-file.sh "/Users/sam/Documents/Quarterly Report.pdf"। যেকোনো রূপই পাথটিকে একটি আর্গুমেন্ট হিসেবে পাস করে; ফাইলটির জন্য স্ক্রিপ্টের রিড পারমিশন (পড়ার অনুমতি) থাকা প্রয়োজন এবং অন্য যেকোনো প্রয়োজনীয় অনুমতি পরিচালনা করতে হবে।
স্ক্রিপ্টের ভেতরে নিরাপদে আর্গুমেন্টটি ব্যবহার করুন
এটিকে process-file.sh নামে সংরক্ষণ করুন:
#!/bin/bash
if [ "$#" -ne 1 ]; then
printf 'Usage: %s FILE\n' "$0" >&2
exit 2
fi
file=$1
if [ ! -f "$file" ]; then
printf 'Not a regular file: %s\n' "$file" >&2
exit 1
fi
printf 'Received one file: %s\n' "$file"
স্ক্রিপ্টটি পরীক্ষা করে দেখে যে এটি ঠিক একটি আর্গুমেন্ট পেয়েছে কিনা, পাথের নামটি একটি রেগুলার ফাইল কিনা তা যাচাই করে এবং প্রাপ্ত পাথটি প্রিন্ট করে। $# হলো আর্গুমেন্টের সংখ্যা; $1 হলো প্রথমটি। কোনো কমান্ডে পাথ পাস করার সময় বা কোনো টেস্টে এটি ব্যবহার করার সময় ভেরিয়েবল এক্সপ্যানশনগুলো উদ্ধৃতি চিহ্নে রাখুন—"$file"। অন্যথায় শেল স্পেসযুক্ত একটি মানকে পৃথক শব্দে বিভক্ত করতে পারে এবং ওয়াইল্ডকার্ড অক্ষরগুলোকে ফাইলের নামের প্যাটার্ন হিসেবে বিবেচনা করতে পারে। ব্যাশ ম্যানুয়ালে পজিশনাল প্যারামিটার এবং শেলের ওয়ার্ড-স্প্লিটিং ও ফাইলনেম-এক্সপ্যানশনের ধাপগুলো নথিভুক্ত করা আছে। Bash Reference Manual: Positional Parameters and Shell Expansions
একাধিক ফাইলের নাম প্রসেস করতে, স্ক্রিপ্টটি চালানোর সময় প্রতিটি পাথ উদ্ধৃতি চিহ্নে রাখুন এবং "$@"-এর ওপর লুপ চালান যাতে প্রতিটি আর্গুমেন্ট আলাদা থাকে:
for file in "$@"; do
printf 'Received: %s\n' "$file"
done
এই উদ্দেশ্যে $* বা উদ্ধৃতিহীন $@ ব্যবহার করবেন না: এগুলো আর্গুমেন্টের মানগুলোকে একত্রিত বা বিভক্ত করতে পারে। যদি স্ক্রিপ্টটি ঠিক একটি ফাইল প্রত্যাশা করে, তবে একটি আর্গুমেন্টের পরীক্ষা বজায় রাখুন এবং একটি কোট করা পাথ পাস করুন।
যখন অ্যাপলস্ক্রিপ্ট শেল কমান্ড চালু করে
একটি AppleScript do shell script কমান্ড শেল কোড ধারণকারী একটি টেক্সট স্ট্রিং গ্রহণ করে। আপনি যদি সরাসরি সেই কমান্ডে একটি পাথ যুক্ত (concatenate) করেন, তবে /Users/sam/Quarterly Reports/report.pdf-এর মতো একটি পাথ একাধিক শেল শব্দ হিসেবে ব্যাখ্যা করা হবে। অ্যাপল শেলের ব্যাখ্যার জন্য নিরাপদ টেক্সট তৈরি করার উপায় হিসেবে quoted form-এর উল্লেখ করেছে, যার মধ্যে স্পেস এবং ভেতরে থাকা কোটেশন চিহ্নযুক্ত স্ট্রিংও অন্তর্ভুক্ত। Apple: Calling Command-Line Tools
পরিচিত কোনো পাথের জন্য, এটিকে যুক্ত করার আগে quoted form of দিয়ে কোট করুন:
set filePath to "/Users/sam/Quarterly Reports/report.pdf"
set safePath to quoted form of filePath
do shell script "/path/to/process-file.sh " & safePath
এর ফলে তৈরি কমান্ডটি স্ক্রিপ্টটিকে একটি পাথ আর্গুমেন্ট প্রদান করে। যদি পাথটি কোনো ফাইল চয়নকারী (file chooser) থেকে আসে, তবে প্রথমে নির্বাচিত আইটেমটিকে একটি POSIX পাথে রূপান্তর করুন, তারপর সেটিকে কোট করুন:
set filePath to POSIX path of (choose file)
do shell script "/path/to/process-file.sh " & quoted form of filePath
অ্যাপলের AppleScript রেফারেন্স নির্বাচিত কোনো ফোল্ডারের জন্য এই প্যাটার্নটি প্রদর্শন করে এবং উল্লেখ করে যে quoted form ভেতরে থাকা সিঙ্গেল কোটও পরিচালনা করে। AppleScript Language Guide: Commands Reference
সাধারণ ত্রুটিগুলো সমাধান করুন
স্ক্রিপ্টটি যদি রিপোর্ট করে যে এটি একাধিক আর্গুমেন্ট পেয়েছে, তবে যে কমান্ডটি এটি চালু করছে তা পরীক্ষা করুন: সম্পূর্ণ পাথটি এক জোড়া উদ্ধৃতি চিহ্নের মধ্যে থাকা উচিত। যদি এটি আক্ষরিক উদ্ধৃতি চিহ্নসহ কোনো পাথ গ্রহণ করে, তবে যাচাই করে দেখুন যে সেই চিহ্নগুলো ফাইলের নামের স্ট্রিংয়েরই অংশ ছিল কিনা; শেলের কোটগুলোর কাজ আর্গুমেন্টটিকে দলভুক্ত করা, এর মানের অংশ হওয়া নয়।
যদি স্ক্রিপ্টটি পাথ সঠিকভাবে গ্রহণ করে কিন্তু পরবর্তী কোনো কমান্ড ব্যর্থ হয়, তবে সেই কমান্ডের আর্গুমেন্টগুলোও পরীক্ষা করুন। লঞ্চ কমান্ডকে উদ্ধৃতি চিহ্নে রাখা স্ক্রিপ্টের ভেতরের কোনো উদ্ধৃতিহীন ভেরিয়েবলকে স্বয়ংক্রিয়ভাবে সুরক্ষিত করে না: some-command "$file"-এর মতো রূপ ব্যবহার করুন। AppleScript-এর ক্ষেত্রে, কোনো পাথের চারপাশে হাতে কোটেশন যোগ করবেন না; শেল কমান্ডের সাথে পাথের quoted form of যুক্ত করুন। এটি কেবল শেলের পার্সিং সংক্রান্ত সমস্যার সমাধান করে। এটি কোনো অবৈধ পাথকে বাস্তব রূপ দেয় না, ফাইল অ্যাক্সেসের অনুমতি প্রদান করে না বা কল করা প্রোগ্রামটি ফাইলটি গ্রহণ করবেই এমন নিশ্চয়তা দেয় না।
উৎসসমূহ
Bash Reference Manual: Quoting — GNU Project
Bash Reference Manual — GNU Project
Mac Automation Scripting Guide: Calling Command-Line Tools — Apple
Commands Reference — Apple