আমাদের ভুলে যাওয়া উচিত নয় যে কার্যটির সারমর্মটি আসলেই বেশ সহজ; হাস্কেলের উপর একটি টিউটোরিয়াল হিসাবে দেওয়া হয়েছে (যা এই কাজের সমাধানের মধ্য দিয়ে লেখা হয়েছে, ক্রমবর্ধমান সংশোধন করা হয়েছে)
এখন আসুন এক মুহুর্তের জন্য আমাদের প্রোগ্রামটি কীভাবে সিউডোকোডে এটি পরিচালনা করবে এবং প্রকাশ করবে:
main = Read list of directories and their sizes.
Decide how to fit them on CD-Rs.
Print solution.
যুক্তিসঙ্গত মনে হচ্ছে? আমিও তাই ভাবছিলাম.
আসুন আমরা আমাদের জীবনকে কিছুটা সহজ করি এবং এখনই ধরে নিই যে আমরা আমাদের প্রোগ্রামের বাইরে কোথাও ডিরেক্টরি আকারগুলি গণনা করব (উদাহরণস্বরূপ, " du -sb *
" সহ) এবং স্টিডিন থেকে এই তথ্যটি পড়ব read
( হাইচিকার্স থেকে হাস্কেল গাইড, অধ্যায় 1 )
(অ্যাডিশালি, আপনার প্রশ্নে, আপনি ফলস্বরূপ ডিস্ক লেআউটগুলি টুইঙ্ক করতে (সম্পাদনা করতে এবং তার বার্ন করার জন্য একটি সরঞ্জাম ব্যবহার করতে সক্ষম হতে চান) use)
আপনার ফাইল সংগ্রহ বিভক্ত করার জন্য সেই হাস্কেল টিউটোরিয়াল থেকে আপনি প্রোগ্রামটির একটি সহজ রূপটি পুনরায় ব্যবহার (অভিযোজিত এবং পুনরায় ব্যবহার) করতে পারেন।
দুর্ভাগ্যবশত, এ টুল যে আমি এখানে অন্য উত্তর উল্লেখিত থাকেন , অপরিহার্য বিভাজন টাস্ক সরলতা জটিলতা এবং ব্যবহারকারি ইন্টারফেসের bloatedness মেলে না হয় (কারণ বেশ কর্ম একত্রিত লেখা হয়েছিল; যদিও পর্যায়ে সম্পাদিত, তবে এখনও আমি যেভাবে পরিষ্কারভাবে ভাবতে পারি তার সাথে মিলিত হয়নি)।distribute
distribute
আপনাকে এর কোডটি কিছুটা ব্যবহার করতে সহায়তা করতে, এখানে distribute
( 380 লাইনে থাকা ) বাশ-কোডের একটি অংশ যা ফাইলগুলির সংগ্রহকে বিভক্ত করার এই "প্রয়োজনীয়" কাজটি সম্পাদন করে:
# Splitting:
function splitMirrorDir() {
if [[ ! -d "$THIS_BASES_DIR/$BASE/$type" ]]; then
echo $"No base fixed for $type" >&2
exit 1
fi
# Getting the list of all suitable files:
local -a allFiles
let 'no = 0' ||:
allFiles=()
# no points to the next free position in allFiles
# allFiles contains the constructed list
for p in "$THIS_BASES_DIR/$BASE/$type"/*.rpm; do
if [[ ! -e "$p" ]]; then
# fail on non-existent files
echo $"Package file doesn't exist: " "$p" >&2
return 1
fi
if [[ "$ONLY_REAL_FILES" == "yes" && ! -f "$p" ]]; then
continue
fi
if [[ "$DIFF_TO_BASE" ]]; then
older_copy="$DIFF_TO_BASE/$type/${p##*/}" # using shell param expansion instead of `basename' to speed up
if [[ -h "$older_copy" || -a "$older_copy" ]]; then
continue
fi
fi
allFiles[$(( no++ ))]="$p"
done
readonly -a allFiles
# Splitting the list of all files into future disks:
#
local -a filesToEat allSizes
let 'no = 0' ||:
filesToEat=()
allSizes=($(getSize "${allFiles[@]}"))
readonly -a allSizes
# allSizes contains the sizes corrsponding to allFiles
# filesToEat hold the constructed list of files to put on the current disk
# no points to the next free position in filesToEat
# totalSize should hold the sum of the sizes
# of the files already put into filesToEat;
# it is set and reset externally.
for p in "${allFiles[@]}"; do
if (( totalsize + ${allSizes[$(( no ))]} > CDVOLUME )); then
eatFiles "${filesToEat[@]}"
filesToEat=()
finishCD
startTypedCD
fi
let "totalsize += ${allSizes[$(( no ))]}" ||:
filesToEat[$(( no++ ))]="$p"
done
eatFiles "${filesToEat[@]}"
}
function eatFiles() {
#{ oldIFS="$IFS"; IFS=$'\n'; echo "$FUNCNAME: args: " "$*" | head >&2; IFS="$oldIFS"; }
zeroDelimited "$@" | xargs -0 --no-run-if-empty \
cp -s \
--target-dir="$THIS_LAYOUTS_DIR/cd$(( cdN ))/$PREFIX/$type$DOT_SUFFIX"/ \
--
}
function startTypedCD() {
# set -x
mkdir -p "$THIS_LAYOUTS_DIR/cd$(( cdN ))/$PREFIX/$type$DOT_SUFFIX"
start_action $" %s with %s" "$(( cdN ))" "$type"
# set +x
}
function finishCD() {
( 454 লাইনের পরে আরও পড়ুন )
নোট করুন যে eatFiles
ফাংশনটি ভবিষ্যতের ডিস্কগুলির লেআউটগুলি গাছ হিসাবে তৈরি করে যেখানে পাতাগুলি আসল ফাইলগুলির সাথে প্রতিচ্ছবিযুক্ত। সুতরাং, এটি আপনার প্রয়োজনীয়তা পূরণ করছে যে আপনার জ্বলনের আগে লেআউটগুলি সম্পাদনা করতে সক্ষম হওয়া উচিত। mkisofs
উপযোগ যা প্রকৃতপক্ষে এর কোডে নিযুক্ত করা হয় symlinks অনুসরণ করার জন্য একটি বিকল্প আছে, আমার mkiso
ফাংশন ।
উপস্থাপিত স্ক্রিপ্ট (যা আপনি নিজের প্রয়োজনে আবার নিতে ও লিখতে পারেন, অবশ্যই!) সহজ ধারণাটি অনুসরণ করে: ফাইলগুলির আকারের (বা আরও সুনির্দিষ্টভাবে প্যাকেজগুলির ক্ষেত্রে distribute
) কেবলমাত্র তাদের তালিকাভুক্ত করা হয়েছে তা যোগ করতে, ডন কোনও পুনর্বিন্যাস করবেন না।
"হাইচাইকার্সকে হাস্কেলের গাইড" অপ্টিমাইজেশান সমস্যাটিকে আরও গুরুত্ব সহকারে নিয়েছে এবং প্রোগ্রামের রূপগুলির পরামর্শ দেয় যা ডিস্কগুলিতে আরও ভাল ফিট করার জন্য (এবং কম ডিস্কের প্রয়োজন হয়) যাতে ফাইলগুলি স্মার্টলি পুনরায় সাজানোর চেষ্টা করবে:
ইতিমধ্যে যথেষ্ট প্রিলিমিনারি রয়েছে। আসুন কিছু সিডি প্যাক করা যাক।
আপনি ইতিমধ্যে স্বীকৃত হতে পারে হিসাবে, আমাদের সমস্যা একটি শাস্ত্রীয় সমস্যা। একে "ন্যাপস্যাক সমস্যা" বলা হয়
( এটি গুগল করুন , যদি আপনি ইতিমধ্যে এটি কী না জানেন তবে 100000 এরও বেশি সংযোগ রয়েছে)।
আসুন লোভী সমাধান থেকে শুরু করি ...
(আরও অধ্যায়ে 3 এবং আরও পড়ুন।)
অন্যান্য স্মার্ট সরঞ্জাম
আমাকে আরও বলা হয়েছে যে ডেবিয়ান তার ডিস্ট্রো সিডিগুলি তৈরি করার জন্য একটি সরঞ্জাম ব্যবহার করে যা আমার distribute
প্যাকেজগুলির সংগ্রহের চেয়ে স্মার্ট : এটির ফলাফলগুলি আরও ভাল কারণ এটি আন্তঃ-প্যাকেজ নির্ভরতার বিষয়ে যত্নশীল এবং প্যাকেজগুলির সংগ্রহগুলি সংগ্রহ করার চেষ্টা করবে on নির্ভরশীলতার অধীনে বন্ধ হওয়া প্রথম ডিস্ক, অর্থাত, 1 ম ডিস্কের কোনও প্যাকেজের জন্য অন্য ডিস্কের কোনও প্যাকেজের প্রয়োজন হবে না (বা কমপক্ষে, আমি বলব, এই জাতীয় নির্ভরতার সংখ্যা হ্রাস করা উচিত)।