সাধারণভাবে ফাইলগুলি প্রতিস্থাপন করা হচ্ছে
প্রথমত, একটি ফাইল প্রতিস্থাপনের জন্য বেশ কয়েকটি কৌশল রয়েছে:
লেখার জন্য বিদ্যমান ফাইলটি খুলুন , এটি 0 দৈর্ঘ্যে কেটে নিন এবং নতুন সামগ্রী লিখুন। (একটি কম সাধারণ বৈকল্পিক হ'ল বিদ্যমান ফাইলটি খোলার জন্য, নতুন সামগ্রীর সাথে পুরানো সামগ্রীটি ওভাররাইট করা, ফাইলটি যদি ছোট হয় তবে নতুন দৈর্ঘ্যে কেটে ফেলা)) শেল পদে:
echo 'new content' >somefile
পুরানো ফাইল সরান , এবং একই নামে একটি নতুন ফাইল তৈরি করুন। শেল পদে:
rm somefile
echo 'new content' >somefile
একটি অস্থায়ী নামে একটি নতুন ফাইল লিখছি তারপর সরানো বিদ্যমান নাম নতুন ফাইল। সরানো পুরানো ফাইল মোছা। শেল পদে:
echo 'new content' >somefile.new
mv somefile.new somefile
আমি কৌশলগুলির মধ্যে সমস্ত পার্থক্য তালিকা করব না, আমি এখানে কিছু গুরুত্বপূর্ণ উল্লেখ করব। রাজ্য 1 এর সাথে, বর্তমানে যদি কোনও প্রক্রিয়া ফাইলটি ব্যবহার করে থাকে তবে প্রক্রিয়াটি নতুন সামগ্রীটিকে আপডেট হওয়ার সাথে সাথে দেখবে। প্রক্রিয়াটি যদি ফাইল সামগ্রীতে একই থাকে বলে আশা করে তবে কিছু বিভ্রান্তি ঘটতে পারে। দ্রষ্টব্য যে এটি কেবল সেই প্রক্রিয়াগুলির বিষয়ে যা ফাইলটি উন্মুক্ত থাকে (যেমন উপস্থিত lsof
বা এতে প্রদর্শিত হয় ; ইন্টারেক্টিভ অ্যাপ্লিকেশনগুলিতে ডকুমেন্ট খোলা থাকে (যেমন সম্পাদকের মধ্যে একটি ফাইল খোলার) সাধারণত ফাইলটি খোলা রাখে না, তারা ফাইলের সময় সামগ্রীটি লোড করে "ওপেন ডকুমেন্ট" অপারেশন এবং তারা "সংরক্ষণ করুন নথি" অপারেশন চলাকালীন (উপরের কৌশলগুলির মধ্যে একটির ব্যবহার করে) ফাইলটি প্রতিস্থাপন করে।/proc/PID/fd/
কৌশল 2 এবং 3 এর সাথে, যদি কোনও প্রক্রিয়াতে ফাইলটি somefile
খোলা থাকে তবে সামগ্রী আপগ্রেড করার সময় পুরানো ফাইলটি উন্মুক্ত থাকে। কৌশল 2 সহ, প্রকৃতপক্ষে ফাইলটি সরানোর পদক্ষেপটি কেবলমাত্র ডিরেক্টরিতে ফাইলের প্রবেশ সরিয়ে দেয়। ফাইলটি কেবল তখনই সরিয়ে ফেলা হয় যখন এতে কোনও ডিরেক্টরি এন্ট্রি না থাকে (সাধারণ ইউনিক্স ফাইল সিস্টেমে একই ফাইলের জন্য একাধিক ডিরেক্টরি এন্ট্রি থাকতে পারে ) এবং কোনও প্রক্রিয়াতে এটি খোলা থাকে না। এটি পর্যবেক্ষণ করার জন্য এখানে একটি উপায় - sleep
প্রক্রিয়াটি মারা যাওয়ার পরে কেবল ফাইলটি সরানো হয় ( rm
কেবলমাত্র এটির ডিরেক্টরি এন্ট্রি সরিয়ে দেয়)।
echo 'old content' >somefile
sleep 9999999 <somefile &
df .
rm somefile
df .
cat /proc/$!/fd/0
kill $!
df .
কৌশল 3 এর সাথে নতুন ফাইলটিকে বিদ্যমান নামে স্থানান্তরিত করার পদক্ষেপটি পুরাতন সামগ্রীর দিকে পরিচালিত ডিরেক্টরি এন্ট্রি সরিয়ে দেয় এবং নতুন সামগ্রীর দিকে পরিচালিত ডিরেক্টরি এন্ট্রি তৈরি করে। এটি একটি পারমাণবিক অপারেশনে করা হয়, সুতরাং এই কৌশলটির একটি বড় সুবিধা রয়েছে: কোনও প্রক্রিয়া যে কোনও সময় ফাইলটি খুললে এটি পুরানো সামগ্রী বা নতুন সামগ্রী দেখতে পাবে - মিশ্র সামগ্রী বা ফাইলটি না পাওয়ার কোনও ঝুঁকি নেই বিদ্যমান।
এক্সিকিউটেবলগুলি প্রতিস্থাপন করা হচ্ছে
যদি আপনি লিনাক্সে চলমান এক্সিকিউটেবলের সাথে কৌশল 1 ব্যবহার করে দেখেন তবে আপনি একটি ত্রুটি পাবেন।
cp /bin/sleep .
./sleep 999999 &
echo oops >|sleep
bash: sleep: Text file busy
একটি "পাঠ্য ফাইল" অর্থ অস্পষ্ট historicalতিহাসিক কারণে নির্বাহযোগ্য কোডযুক্ত এমন একটি ফাইল । অন্যান্য অনেক ইউনিক্স রূপের মতো লিনাক্স চলমান প্রোগ্রামের কোডটি ওভাররাইট করতে অস্বীকার করে; কয়েকটি ইউনিক ভেরিয়েন্ট এটির অনুমতি দেয়, পুরানো কোডটি যদিও খুব ভালভাবে বহির্মুখী পরিবর্তন না করে নতুন কোডটি ক্রাশ হয়ে যায়।
লিনাক্সে, আপনি গতিশীল লোড লাইব্রেরির কোডটি ওভাররাইট করতে পারেন। এটি সম্ভবত এটির যে প্রোগ্রামটি ব্যবহার করছে তাতে ক্রাশ হতে পারে। (আপনি sleep
এটি এটির সাথে পর্যবেক্ষণ করতে সক্ষম হবেন না কারণ এটি শুরু হওয়ার সাথে সাথে এটি প্রয়োজনীয় সমস্ত লাইব্রেরি কোড লোড করে দেয় sleeping ঘুমানোর পরে দরকারী কিছু কার্যকর করার মতো আরও জটিল প্রোগ্রাম চেষ্টা করুন like perl -e 'sleep 9; print lc $ARGV[0]'
)
যদি কোনও দোভাষী কোনও স্ক্রিপ্ট চালাচ্ছেন, স্ক্রিপ্ট ফাইলটি দোভাষী দ্বারা একটি সাধারণ উপায়ে খোলা হয়, সুতরাং স্ক্রিপ্টটি ওভাররাইটিংয়ের বিরুদ্ধে কোনও সুরক্ষা নেই। কিছু দোভাষী তাদের প্রথম লাইনটি কার্যকর করা শুরু করার আগে পুরো স্ক্রিপ্টটি পড়ে এবং বিশ্লেষণ করে, অন্যরা স্ক্রিপ্টটি প্রয়োজনমতো পড়েন। দেখুন আপনি কার্যকর করার সময় কোনও স্ক্রিপ্ট সম্পাদনা করলে কী হয়? এবং লিনাক্স শেল স্ক্রিপ্টগুলির সাথে কীভাবে আচরণ করে? বিস্তারিত জানার জন্য.
2 এবং 3 কৌশলগুলি এক্সিকিউটেবলের জন্যও নিরাপদ: চালানো এক্সিকিউটেবল (এবং ডায়নামিকভাবে লোড করা লাইব্রেরিগুলি) কোনও ফাইল বিবরণীকারী অর্থে ফাইলগুলি না খোলায়, তারা খুব একইভাবে আচরণ করে। যতক্ষণ না কিছু প্রোগ্রাম কোড চালাচ্ছে ততক্ষণ ডিরেক্টরি এন্ট্রি ছাড়াই ফাইলটি ডিস্কে থেকে যায়।
একটি অ্যাপ্লিকেশন আপগ্রেড
উপরে উল্লিখিত সর্বাধিক সুবিধার কারণে বেশিরভাগ প্যাকেজ ম্যানেজার ফাইল 3 প্রতিস্থাপনের জন্য কৌশল ব্যবহার করেন - সময় সময়ে যে কোনও সময় ফাইলটি খোলার ফলে এটির বৈধ সংস্করণ দেখা যায়।
অ্যাপ্লিকেশন আপগ্রেডগুলি যেখানে ভাঙ্গতে পারে তা হ'ল কোনও ফাইল আপগ্রেড করার সময় পারমাণবিক হয়, অ্যাপ্লিকেশনটিকে সামগ্রিকভাবে আপগ্রেড করা যদি অ্যাপ্লিকেশনটিতে একাধিক ফাইল (প্রোগ্রাম, গ্রন্থাগার, ডেটা,…) থাকে তবে তা নয়। ইভেন্টগুলির নিম্নলিখিত ক্রমটি বিবেচনা করুন:
- অ্যাপ্লিকেশনটির একটি উদাহরণ শুরু হয়েছে।
- অ্যাপ্লিকেশনটি আপগ্রেড করা হয়েছে।
- চলমান উদাহরণ অ্যাপ্লিকেশন এর একটি ডেটা ফাইল খুলবে।
পদক্ষেপ 3 এ, অ্যাপ্লিকেশনটির পুরানো সংস্করণটির চলমান দৃষ্টান্ত নতুন সংস্করণ থেকে একটি ডেটা ফাইল খুলছে। এটি অ্যাপ্লিকেশনটির উপর নির্ভর করে কিনা তা কোনও ফাইলের এবং ফাইলটি কতটা সংশোধন করা হয়েছে তার উপর নির্ভর করে।
একটি আপগ্রেড করার পরে, আপনি নোট করবেন যে পুরানো প্রোগ্রামটি এখনও চলছে। আপনি যদি নতুন সংস্করণটি চালাতে চান তবে আপনাকে পুরানো প্রোগ্রামটি থেকে বেরিয়ে নতুন সংস্করণটি চালাতে হবে। প্যাকেজ পরিচালনাকারীরা সাধারণত একটি আপগ্রেডে ডেমনগুলি হত্যা করে পুনরায় চালু করে তবে শেষ-ব্যবহারকারী অ্যাপ্লিকেশনকে একা রেখে দেয়।
কিছু ডেমনের ডেমনকে হত্যা না করেই আপগ্রেডগুলি পরিচালনা করার জন্য বিশেষ পদ্ধতি রয়েছে এবং নতুন দৃষ্টান্তটি পুনরায় আরম্ভের জন্য অপেক্ষা করুন (যা কোনও পরিষেবার ক্ষেত্রে বাধা সৃষ্টি করে)। এটি init এর ক্ষেত্রে প্রয়োজনীয় , যা হত্যা করা যায় না; init সিস্টেমগুলি অনুরোধ করার একটি উপায় সরবরাহ করে যাতে চলমান দৃষ্টান্তটি execve
নতুন সংস্করণে নিজেকে প্রতিস্থাপন করতে কল করে।