এটি উপলব্ধি করা গুরুত্বপূর্ণ যে এটি আসলে শেল যা foo*
মেলানো ফাইলের নামের তালিকায় এটি প্রসারিত করে , তাই mv
এটি নিজেই কিছু করতে পারে।
এখানে সমস্যাটি হ'ল যখন কোনও গ্লোব মেলে না, তখন কিছু শেল bash
(এবং বেশিরভাগ বোর্নের মতো শেলস, যে বগি আচরণটি আসলে বোর্ন শেল দ্বারা s০ এর দশকের শেষের দিকে প্রবর্তিত হয়েছিল) কমান্ডটিতে প্যাটার্ন ভারব্যাটিমটি পাস করে।
তাই এখানে, যখন foo*
কোন ফাইল, পরিবর্তে কমান্ড (প্রাক বোর্ন শাঁস এবং বিভিন্ন আধুনিক শাঁস মত না) গর্ভপাত এর সাথে মেলে না, শেল একটি ধারণকৃত পাসের foo*
ফাইল mv
, তাই মূলত জিজ্ঞাসা mv
নামক ফাইল স্থানান্তর করতে foo*
।
এই ফাইলটির অস্তিত্ব নেই। যদি এটি হয়ে থাকে তবে এটি আসলে প্যাটার্নটির সাথে মিলেছে তাই mv
কোনও ত্রুটির কথা জানায়। যদি প্যাটার্নটি foo[xy]
পরিবর্তিত হয়ে mv
থাকে তবে ভুলক্রমে ফাইল এবং ফাইলগুলির foo[xy]
পরিবর্তে কল করা কোনও ফাইল সরিয়ে নিতে পারত ।foox
fooy
এখন, এমনকি সেই শেলগুলিতেও যে সমস্যা নেই (প্রাক-বোর্ন, সিএসএস, টিসিএস, ফিশ, জেডএস, বাশ-ও ফেলগ্লোব) আপনি এখনও ত্রুটি পেয়ে যাবেন mv foo* ~/bar
, তবে এবার শেলের সাহায্যে।
যদি কোনও ফাইলের মিল নেই foo*
এবং সে ক্ষেত্রে কোনও কিছুই না সরানো হয় তবে আপনি এটিকে ত্রুটি হিসাবে বিবেচনা করতে না চাইলে আপনি প্রথমে ফাইলগুলির তালিকা তৈরি করতে চান (এমনভাবে যা nullglob
বিকল্পটির বিকল্পটি ব্যবহার করে কোনও ত্রুটি সৃষ্টি করে না কিছু শেল) এবং তারপরে কেবল কলটি mv
তালিকাটি খালি নয়।
এটি সমস্ত ত্রুটিগুলি mv
(যেমন যুক্ত করা 2> /dev/null
) গোপন করার চেয়ে ভাল হবে যেন mv
অন্য কোনও কারণে ব্যর্থ হয় তবে আপনি সম্ভবত এটি কেন জানতে চান।
zsh এ
files=(foo*(N)) # where the N glob qualifier activates nullglob for that glob
(($#files == 0)) || mv -- $files ~/bar/
বা অস্থায়ী পরিবর্তনশীল ব্যবহার এড়াতে একটি বেনামি ফাংশন ব্যবহার করুন:
() { (($# == 0)) || mv -- "$@" ~/bar/; } foo*(N)
zsh
সেই শেলগুলির মধ্যে একটি যা বোর্ন বাগ নেই এবং কোনও গ্লোব মেলে না (এবং nullglob
বিকল্পটি সক্ষম করা হয়নি) কমান্ডটি কার্যকর না করেই ত্রুটির খবর দেয় , সুতরাং এখানে আপনি zsh
ত্রুটিটি আড়াল করে পুনরুদ্ধার করতে পারবেন stderr এর জন্য mv
আপনি এখনও mv
যদি ত্রুটিগুলি দেখতে পান তবে কোনও মিল না হওয়া গ্লোবগুলি সম্পর্কে ত্রুটি নয়:
(mv 2>&3 foo* ~/bar/) 3>&2 2>&-
অথবা আপনি zargs
যদি এমন সমস্যাগুলি এড়াতে পারেন যা foo*
বিশ্বব্যাপী খুব ম্যান ফাইলগুলিতে প্রসারিত হয় তবে সমস্যাগুলি এড়ানো যাবে।
autoload zargs # best in ~/.zshrc
zargs -r -- foo* -- mv -t ~/bar # here assuming GNU mv for its -t option
Ksh93 এ:
files=(~(N)foo*)
((${#files[#]} == 0)) || mv -- "${files[@]}" ~/bar/
ব্যাশে:
bash
nullglob
শুধুমাত্র একটি গ্লোব সক্ষম করার জন্য কোনও সিনট্যাক্স নেই এবং failglob
বিকল্পটি বাতিল হয়ে যায় nullglob
যাতে আপনার মতো জিনিসগুলির প্রয়োজন হয়:
saved=$(shopt -p nullglob failglob) || true
shopt -s nullglob
shopt -u failglob
files=(foo*)
((${#files[@]} == 0)) || mv -- "${files[@]}" ~/bar/
eval "$saved"
বা সংরক্ষণের জন্য বিকল্পগুলিকে সেট করে সেভ করার জন্য সেগুলি আগে সংরক্ষণ করতে হবে এবং পরে তাদের পুনরুদ্ধার করতে হবে।
(
shopt -s nullglob
shopt -u failglob
files=(foo*)
((${#files[@]} == 0)) || mv -- "${files[@]}" ~/bar/
)
মধ্যে yash
(
set -o nullglob
files=(foo*)
[ "${#files[@]}" -eq 0 ] || mv -- "${files[@]}" ~/bar/
)
মধ্যে fish
ফিশ শেলের মধ্যে নাল্লোগ্লোব আচরণটি set
কমান্ডের জন্য ডিফল্ট , সুতরাং এটি ঠিক:
set files foo*
count $files > /dev/null; and mv -- $files ~/bar/
POSIXly
nullglob
পসিক্সে কোনও বিকল্প নেই sh
এবং অবস্থানগত পরামিতিগুলি ছাড়া অন্য কোনও অ্যারে নেই। গ্লোব মিলছে কি না তা সনাক্ত করতে আপনি ব্যবহার করতে পারেন এমন একটি কৌশল রয়েছে:
set -- foo[*] foo*
if [ "$1$2" != 'foo[*]foo*' ]; then
shift
mv -- "$@" ~/bar/
fi
একটি foo[*]
এবং foo*
গ্লোব উভয়ই ব্যবহার করে আমরা সেই ক্ষেত্রে যেখানে কোনও মিল নেই এমন ফাইলের মধ্যে এবং যেখানে একটি ফাইল রয়েছে যেখানে ডাকা হয় তার মধ্যে পার্থক্য করতে পারি foo*
(যা set -- foo*
করতে পারে না)।
আরও পড়া:
mv foo* ~/bar/ 2> /dev/null
?