সতর্কতা: এর যে কোনও সমাধানের সাথে আপনার সচেতন হওয়া দরকার যে আপনি ডেটা ফাইলগুলির সুরক্ষার জন্য অখণ্ডতার উপর বিশ্বাস করছেন কারণ সেগুলি আপনার স্ক্রিপ্টে শেল কোড হিসাবে কার্যকর হবে। এগুলি সুরক্ষিত করা আপনার স্ক্রিপ্টের সুরক্ষার পক্ষে সর্বকাম!
এক বা একাধিক ভেরিয়েবল সিরিয়াল করার জন্য সহজ ইনলাইন প্রয়োগ implementation
হ্যাঁ, ব্যাশ এবং জ্যাশ উভয় ক্ষেত্রেই আপনি কোনও ভেরিয়েবলের বিষয়বস্তু এমনভাবে সিরিয়ালাইজ করতে পারেন যা typesetবিল্টিন এবং -pযুক্তি ব্যবহার করে পুনরুদ্ধার করা সহজ । আউটপুট বিন্যাসটি এমন যে আপনি sourceনিজের জিনিসগুলি ফিরে পেতে কেবল আউটপুট নিতে পারেন।
# You have variable(s) $FOO and $BAR already with your stuff
typeset -p FOO BAR > ./serialized_data.sh
আপনি আপনার জিনিসগুলি আবার আপনার স্ক্রিপ্টে বা অন্য স্ক্রিপ্টে পুরোপুরি ফিরে পেতে পারেন:
# Load up the serialized data back into the current shell
source serialized_data.sh
এটি বিভিন্ন শেলের মধ্যে ডেটা পাশ করার সাথে সাথে ব্যাশ, জেডএস এবং কেএস এর জন্য কাজ করবে। বাশ তার বিল্টিন declareফাংশনটিতে এটি অনুবাদ করবে যখন zsh এটি প্রয়োগ করে তবে কেএসএসের সামঞ্জস্যের typesetজন্য আমরা typesetএখানে যেভাবেই ব্যবহার করি তার জন্য ব্যাশের একটি উপাধ রয়েছে।
ফাংশন ব্যবহার করে আরও জটিল সাধারণীকরণের বাস্তবায়ন
উপরের বাস্তবায়নটি সত্যিই সহজ, তবে আপনি যদি এটি ঘন ঘন কল করেন তবে আপনি নিজেকে আরও সহজ করার জন্য একটি ইউটিলিটি ফাংশন দিতে চাইতে পারেন। অতিরিক্ত হিসাবে আপনি যদি কখনও উপরোক্ত কাস্টম ফাংশনগুলির মধ্যে অন্তর্ভুক্ত করার চেষ্টা করেন তবে আপনি ভেরিয়েবল স্কোপিংয়ের সমস্যাগুলিতে চলে যাবেন। এই সংস্করণে এই সমস্যাগুলি মুছে ফেলা উচিত।
এগুলির জন্য নোট করুন, ব্যাশ / জেডএস ক্রস-সামঞ্জস্যতা বজায় রাখার জন্য আমরা উভয় ক্ষেত্রেই ঠিক করব typesetএবং declareসুতরাং কোডটি উভয় শেলের মধ্যে কাজ করা উচিত। এটি কিছু বাল্ক এবং গণ্ডগোল যোগ করে যা আপনি যদি কেবলমাত্র একটি শেল বা অন্য একটির জন্য এটি করে থাকেন তবে তা মুছে ফেলা হতে পারে।
এর জন্য ফাংশনগুলি ব্যবহার করার (বা অন্যান্য ফাংশনের কোড সহ) প্রধান সমস্যাটি হ'ল typesetফাংশনটি এমন একটি কোড উত্পন্ন করে যা কোনও ফাংশনের অভ্যন্তর থেকে কোনও স্ক্রিপ্টে ফিরিয়ে নেওয়া হলে গ্লোবালটির পরিবর্তে স্থানীয় পরিবর্তনশীল তৈরিতে ডিফল্ট হয়।
এটি বেশ কয়েকটি হ্যাকের একটিতে স্থির করা যেতে পারে। এটি ঠিক করার জন্য আমার প্রাথমিক প্রয়াসটি পতাকা sedযোগ করার জন্য সিরিয়ালাইজ প্রক্রিয়াটির আউটপুটকে পার্স করা হয়েছিল -gযাতে তৈরি কোডটি যখন স্রোসিত হয় তখন গ্লোবাল ভেরিয়েবলকে সংজ্ঞায়িত করে।
serialize() {
typeset -p "$1" | sed -E '0,/^(typeset|declare)/{s/ / -g /}' > "./serialized_$1.sh"
}
deserialize() {
source "./serialized_$1.sh"
}
নোট করুন যে ফানসি sedএক্সপ্রেশনটি কেবল 'টাইপসেট' বা 'ডিক্লেয়ার' এর প্রথম ঘটনার সাথে মেলে এবং -gপ্রথম যুক্তি হিসাবে যুক্ত করা। এটি কেবলমাত্র প্রথম ঘটনার সাথেই মিলিত হওয়া প্রয়োজন কারণ স্টাফেন চাজেলাস যথাযথভাবে মন্তব্যে উল্লেখ করেছেন, অন্যথায় এটি এমন ক্ষেত্রেও মিলবে যেখানে সিরিয়ালযুক্ত স্ট্রিংয়ে ডিক্লার বা টাইপসেট শব্দের পরে আক্ষরিক নিউলাইন রয়েছে।
আমার প্রাথমিক পার্সিংয়ের ভুল পার্সকে সংশোধন করার পাশাপাশি স্টাফেন এটি হ্যাক করার জন্য একটি কম ভঙ্গুর উপায়ও বলেছিল যা কেবল স্ট্রিংগুলি পার্সিংয়ের সাথে সমস্যার সমাধান করে না তবে ক্রিয়াগুলি নতুন করে সংজ্ঞায়িত করার জন্য একটি মোড়ক ফাংশন ব্যবহার করে অতিরিক্ত কার্যকারিতা যুক্ত করার জন্য দরকারী হুক হতে পারে ডেটা ফেরত দেওয়ার সময় নেওয়া হয়েছিল This এটি ধরে নেওয়া হয় আপনি ঘোষিত বা টাইপসেট আদেশগুলি দিয়ে অন্য কোনও গেম খেলছেন না, তবে এই কৌশলটি আপনার নিজের বা অন্য কোনও ক্রিয়াকলাপের অংশ হিসাবে আপনি যখন এই কার্যকারিতাটি অন্তর্ভুক্ত করেছিলেন এমন পরিস্থিতিতে কার্যকর করা সহজ হবে or আপনি ডেটা লিখিত হচ্ছে এবং -gপতাকাটি যুক্ত হয়েছে কিনা তা আপনার নিয়ন্ত্রণে ছিল না । অনুরূপ কিছু উপকরণের সাথেও করা যেতে পারে, বাস্তবায়নের জন্য গিলসের উত্তর দেখুন ।
ফলাফলটিকে আরও কার্যকর করতে আমরা আর্গুমেন্ট অ্যারের প্রতিটি শব্দ একটি ভেরিয়েবলের নাম ধরে ধরে আমাদের ফাংশনগুলিতে একাধিক ভেরিয়েবলগুলি পুনরুক্ত করতে পারি। ফলাফলটি এরকম কিছু হয়ে যায়:
serialize() {
for var in $@; do
typeset -p "$var" > "./serialized_$var.sh"
done
}
deserialize() {
declare() { builtin declare -g "$@"; }
typeset() { builtin typeset -g "$@"; }
for var in $@; do
source "./serialized_$var.sh"
done
unset -f declare typeset
}
উভয় সমাধানের সাহায্যে ব্যবহারটি দেখতে এই রকম হবে:
# Load some test data into variables
FOO=(an array or something)
BAR=$(uptime)
# Save it out to our serialized data files
serialize FOO BAR
# For testing purposes unset the variables to we know if it worked
unset FOO BAR
# Load the data back in from out data files
deserialize FOO BAR
echo "FOO: $FOO\nBAR: $BAR"