কম্পিউটার টিউটোরিয়াল

স্ট্রিমলাইনড উবুন্টু ডেস্কটপ সেটআপ: আপনার ডটফাইলস ও বাশ স্ক্রিপ্টস অটোমেট করুন

গিটহাবে (GitHub) ওপেন সোর্স ফাইলস (open source files) সম্পর্কে আমার সবচেয়ে প্রিয় चीজों একটা হচ্ছে অন্যরা কীভাবে করত he তা দেখার সুযোগ - যেসব কিছু লোক "মান্ডেন" (mundane) বলতে পারে, যেন তাদের .bashrc এবং অন্যান্য ডটফাইলস (dotfiles) সেটআপ করা। যেতে আমি যখন লিনাক্স সাইডে (Linux side) আসলাম তখন আমি রাইসিং (ricing) নিয়ে যত энথুসিয়াস্টিক (enthusiastic) ছিলাম তত নাও, আমি এখনও প্রিটি এক্সাইটেড (pretty excited) হই যখন আমি এমন কোনো কনফিগ সেটিং (config setting) পাই যা জিনিসগুলো প্রিটিয়ার (prettier) এবং ফাস্টার (faster) করে, এবং তাই, बेटার (better)।

আমি gầnে এমন কিছু জিনিস পেলাম, বিশেষ করে টম হাডসনের (Tom Hudson's) ডটফাইলসে। টম লাগে স্ক্রিপ্টিং (scripting) পছন্দ, এবং সেই জিনিসগুলোর মধ্যে আছে অটোমেটিক্যালি সিম্বলিক লিংকস (symlinks) সেটআপ করা, এবং উবুন্টু রিপোজিটরি অ্যাপ্লিকেশনস (Ubuntu repository applications) এবং অন্যান্য প্রোগ্রামস ইনস্টল করা। এটা আমাকে চিন্তা করতে বাধ্য করল। কি আমি একটি নতুন মেশিনের সেটআপ অটোমেট করতে পারি আমার বর্তমানটির রিপ্লিকেট (replicate) করতে?

যে কেউ জিনিসগুলো আলাদা করে দেখতে পছন্দ করে কীভাবে সেগুলো কাজ করে, আমি মাঝেমাঝে আমার ল্যাপটপ মেস আপ (mess up) করি। (সাধারণত যখন আমি বাড়ি থেকে দূরে থাকি, এবং আমার ব্যাকআপ হার্ডড্রাইভ (backup harddrive) নেই।) সেসব রেয়ার (rare) কিন্তু সত্যিকারের ইনকনভেনিয়েন্ট (inconvenient) সिचুয়েশনগুলোতে যখন আমার কম্পিউটার তার سابق রূপের একটি শেল (shell) হয়ে যায়, (বা-ডাম-চিং) তখন হাম্পটি ডাম্পটি (Humpty Dumpty) আবার যেনে যেনে যেনে (just the way I like) জোড়া দিতে একটি ফাস্ট (fast), সিম্পল (simple) উপায় থাকা খুব নাইস (nice) হতো।

একটি ডিস্ক ইমেজ (disk image) তৈরি করে পরে রিস্টোর (restore) করার বিপরীতে, বাশ স্ক্রিপ্টস (bash scripts) একটি কালেকশন (collection) তৈরি করা, মেইনটেইন (maintain) করা, এবং মুভ (move) করা সহজ। এগুলোর কোনো স্পেশাল ইউটিলিটি (special utilities) লাগে না, শুধু একটি এক্সটার্নাল ট্রান্সপোর্টেশন মেথড (external transportation method)। এটা রেসিপি (recipe) পাস করার মত, পুরো বান্ট কেক (bundt cake) না। (মম, কেক।)

এছাড়া, এই ফাংশনালিটি (functionality) সুপার উপযোগী হবে যখন একটি ভার্চুয়াল মেশিন (virtual machine, VM), বা এমনকি একটি ভার্চুয়াল প্রাইভেট সার্ভার (virtual private server, VPS) সেটআপ করা হবে। (এই দুটোই, এখন আমি এটা লিখতে লিখতে মনে করছি, আমার আরও ডিস্ট্রাক্টিভ (destructive) এক্সপেরিমেন্টস (experimentations)-এর জন্য আরও ফরগিভিং (forgiving) টার্গেটস (targets) হতো... লিভ অ্যান্ড লার্ন!)

খুবসুরত, কিছু গ্রেপ (greping) এবং গুগলিং (Googling) এবং খুঁজে বের করার পর, আমার এখন একটি স্যুট (suite) আছে স্ক্রিপ্টস (scripts) যেগুলো এটি করতে পারে:

স্ট্রিমলাইনড উবুন্টু ডেস্কটপ সেটআপ: আপনার ডটফাইলস ও বাশ স্ক্রিপ্টস অটোমেট করুন

সেটআপটির একটি ভিডিও এখানে দেখুন।

এটি একটি ফ্রেশ (fresh) উবুন্টু ডেস্কটপে সেটআপ স্ক্রিপ্টস (setup scripts) এর একটি টেস্ট রান (test run)-র টেইল এন্ড (tail end), বুটেবল USB (bootable USB) দিয়ে লোডেড। এতে ৩ মিনিটের কম সময়ে আমার সকল প্রোগ্রাম এবং সেটিংস রিস্টোর (restored) হয়েছিল!

এই পোস্ট কভার করবে কীভাবে একটি কম্পিউটার যেটি উবুন্টু ডেস্কটপ (আমার কেসে, উবুন্টু LTS 18.04) চলে সেটি বাশ স্ক্রিপ্টস (bash scripts) ব্যবহার করে অটোমেটিক্যালি সেটআপ করা যায়। কভার করা ইনফরমেশন-এর অধিকাংশ সকল লিনাক্স ডেস্কটপ ফ্লেভার্স (Linux desktop flavours)-এ প্রযোজ্য, যদিও কিছু সিনট্যাক্স ভিন্ন হতে পারে। বাশ স্ক্রিপ্টস তিনটি প্রধান এরিয়া (areas) কভার করে: ডটফাইলস লিংকিং (linking dotfiles), উবুন্টু এবং অন্য জায়গা থেকে সফ্টওয়্যার ইনস্টল করা, এবং ডেস্কটপ এনভায়রনমেন্ট সেটআপ করা। আমরা প্রতিটি এরিয়া কভার করব এবং গুরুত্বপূর্ণ পয়েন্টগুলো ওভারভিউ করব যাতে আপনি আপনার নিজের স্ক্রিপ্টস বানাতে শুরু করতে পারেন।

ডটফাইলস (Dotfiles)

ডটফাইলস হলো যা অধিকাংশ লিনাক্স এंथুসিয়াস্ট (Linux enthusiasts) কনফিগারেশন ফাইলস (configuration files) বলেন। সেগুলো সাধারণত ইউজারের হোম ডিরেক্টরিতে বাস করে (বাশ স্ক্রিপ্টসে বিল্টইন ভেরিয়েবল $HOME দিয়ে ডেনোট করা হয়) এবং সকল প্রকার প্রোগ্রামের আপিয়ারেন্স (appearance) এবং বিহেভিয়র (behaviour) কন্ট্রোল করে। ফাইল নামগুলো . দিয়ে শুরু হয়, যা লিনাক্সে হিডেন ফাইলস (hidden files) বোঝায় (তাই "ডট" ফাইলস)। কিছু কমন ডটফাইলস এবং সেগুলো কীভাবে উপযোগী সেটি নিচে দেওয়া হলো।

.bashrc

.bashrc ফাইল হচ্ছে একটি কমান্ড লিস্ট যা ইন্টারঅ্যাক্টিভ (interactive), নন-লগইন শেলস (non-login shells) দ্বারা স্টার্টআপে এক্সিকিউট (executed) হয়। ইন্টারঅ্যাক্টিভ ভালে নন-ইন্টারঅ্যাক্টিভ শেলস (interactive vs non-interactive shells) একটু কনফিউজিং (confusing) হতে পারে, কিন্তু এখানে আমাদের চিন্তা করার প্রয়োজন নেই। আমাদের উদ্দেশ্যে, যেকোনো সময় আপনি একটি নতুন টার্মিনাল খুলেন, একটি প্রম্পট (prompt) দেখেন, এবং সেখানে কমান্ড টাইপ করতে পারেন, আপনার .bashrc এক্সিকিউট হয়েছিল।

এই ফাইলের লাইনগুলো আপনার ওয়ার্কফ্লো উন্নত করতে পারে এলিয়াস (aliases) তৈরি করে যা কীস্ট্রোকস (keystrokes) কমিয়ে দেয়, বা একটি হেল্পফুল প্রম্পট (helpful prompt) ডিসপ্লে করে উপযোগী ইনফরমেশনসহ। এটি ইউজার-ক্রিয়েটেড (user-created) প্রোগ্রামসও রান করতে পারে, যেন এডি (Eddie)। আরও আইডিয়ার জন্য, আপনি আমার গিটহাবে (GitHub) .bashrc ফাইল দেখতে পারেন।

.vimrc

.vimrc ডটফাইল কনফিগার করে সকল টেক্সট এডিটরসের চ্যাম্পিয়ন (champion), ভিম (Vim)। (আপনি যদি এখনও কীবোর্ড শর্টকাটস (keyboard shortcuts)-এর পাওয়ারস (powers) চালাতে না পারেন, আমি স্ট্রংলি রিকমেন্ড (strongly recommend) করি ভিম শিখতে একটি ফান গেম (fun game) দিয়ে।)

.vimrc-এ, আমরা এডিটর প্রিফারেন্সেস (editor preferences) সেট করতে পারি যেন ডিসপ্লে সেটিংস, কালারস, এবং কাস্টম কীবোর্ড শর্টকাটস। আপনি আমার গিটহাবে .vimrc দেখতে পারেন।

অন্যান্য ডটফাইলসও উপযোগী হতে পারে আপনার ব্যবহৃত প্রোগ্রামগুলোর উপর নির্ভর করে, যেন .gitconfig বা .tmux.conf। গিটহাবে ডটফাইলস এক্সপ্লোর (explore) করা আপনার জন্য কী উপলব্ধ এবং উপযোগী সেটি বুঝতে একটি চমৎকার উপায়!

ডটফাইলস লিংকিং (Linking dotfiles)

আমরা একটি স্ক্রিপ্ট ব্যবহার করতে পারি সিম্বলিক লিংকস (symbolic links), বা সিমলিংকস (symlinks) তৈরি করার জন্য সকল আমাদের ডটফাইলসের। এটি আমাদের দেয় সুযোগ সকল ফাইলগুলো একটি সেন্ট্রাল রিপোজিটরি (central repository) তে রাখা যাতে সেগুলো সহজে ম্যানেজ (manage) করা যায়, একই সাথে একটি সর্ট অফ প্লেসহোল্ডার (sort of placeholder) দেয় সেটি স্পоте যেখানে আমাদের প্রোগ্রামগুলো কনফিগারেশন ফাইল খুঁজতে এক্সপেক্ট (expect) করে। এটি সাধারণত, কিন্তু সবসময় নয়, ইউজার হোম ডিরেক্টরি। উদাহরণস্বরূপ, যেহেতু আমি আমার ডটফাইলস গিটহাবে (GitHub) স্টোর করি, আমি সেগুলো একটি ডিরেক্টরিতে রাখি যেন ~/github/dotfiles/ পাথ (path) এর মত, যখন ফাইলগুলো সিমলিংকড (symlinked) থাকে, ফলাফলস্বরূপ পাথ হয় ~/.vimrc।

প্রোগ্রাম্যাটিক্যালি (programmatically) যেকোনো বিদ্যমান ফাইল এবং সিমলিংক চেক করে এবং হ্যান্ডেল (handle) করে, তারপর নতুন তৈরি করতে, আমরা এই এলিগেন্ট (elegant) শেল স্ক্রিপ্ট ব্যবহার করতে পারি। আমি এটিকে কোম্প্লিমেন্ট (compliment) করছি শুধু কারণ আমি এর কোর (core) টমের (Tom's) সেটআপ স্ক্রিপ্ট (setup script) থেকে ব্লাট্যান্টলি (blatantly) চুরি করেছি, তাই আমি কেমন এর ক্যাস্ট (credit) নিতে পারি না কতই এলিগেন্ট (elegant) এটি।

symlink.sh স্ক্রিপ্টটি কাজ করে আমাদের $HOME-এ প্রতিটি ডটফাইলের জন্য সিমলিংক তৈরি করার চেষ্টা করিয়ে। এটি প্রথমে চেক করে দেখে একটি সিমলিংক ইতিমধ্যে আছে কিনা, বা সেম নাম (same name) দিয়ে একটি রেগুলার ফাইল বা ডিরেক্টরি আছে কিনা। পূর্বের কেসে, সিমলিংকটি রিমুভ (removed) এবং রিমেড (remade); পরবর্তীতে, ফাইল বা ডিরেক্টরিটি রিনেম (renamed) করা হয়, তারপর সিমলিংক তৈরি হয়।

সফ্টওয়্যার ইনস্টল করা (Installing software)

শেল স্ক্রিপ্টস (shell scripts) এক্সপ্লোর (explore) করার সবচেয়ে সুন্দর জিনিসগুলোর একটা হচ্ছে শুধু কমান্ড লাইন (command line) ব্যবহার করে কতটুকু অর্জন করা যায় সেটি আবিষ্কার করা। যেসব কেউ যাদের কম্পিউটারসের প্রথম এক্সপোজার (exposure) গ্রাফিক্যাল অপারেটিং সিস্টেম (graphical operating system) দিয়ে হয়েছিল, তাদের জন্য টার্মিনালে (terminal) কাজ করা রিফ্রেশিংলি ফাস্ট (refreshingly fast)।

উবুন্টু (Ubuntu)-তে, অধিকাংশ প্রোগ্রাম যা আমরা লাইকلی (likely) রিকোয়ার (require) করি, ডিফল্ট উবুন্টু সফ্টওয়্যার রিপোজিটরিজ (Ubuntu software repositories) দিয়ে উপলব্ধ। আমরা সাধারণত এগুলো সার্চ (search) করি কমান্ড apt search দিয়ে এবং ইনস্টল (install) করি sudo apt install দিয়ে। কিছু সফ্টওয়্যার যা আমরা চাই সেটি ডিফল্ট রিপোজিটরিজে নাও থাকতে পারে, বা সেখানে সবচেয়ে কারেন্ট ভার্সন (current version) অফার (offer) করা নাও থাকতে পারে। এই কেসগুলোতে, আমরা এখনও এই প্রোগ্রামগুলো উবুন্টুতে ইনস্টল করতে পারি একটি PPA, বা পার্সনাল প্যাকেজ আর্কাইভ (Personal Package Archive) ব্যবহার করে। আমাদের শুধু খেয়াল রাখতে হবে যে আমরা যেসব PPA চয়েস (choose) করি সেগুলো অফিসিয়াল সোর্সেস (official sources) থেকে হয়।

যদি একটি প্রোগ্রাম যা আমরা চাই ডিফল্ট রিপোজিটরিজে দেখা নাও যায় বা মনে হয় সেটির কোনো PPA নেই, তবে আমরা এখনও সেটি কমান্ড লাইন দিয়ে ইনস্টল করতে পারি। "installation command line" দিয়ে একটি কুইক সার্চ (quick search) কিছু আন্সার (answers) দেবে।

যেহেতু বাশ স্ক্রিপ্টস (bash scripts) শুধু কমান্ডস (commands) একটি কালেকশন (collection) যা আমরা ইন্ডিভিডুয়ালি (individually) টার্মিনালে রান (run) করতে পারতাম, সকল আমাদের পছন্দসই প্রোগ্রামস ইনস্টল করার একটি স্ক্রিপ্ট তৈরি করা যেন একইভাবে সহজ হচ্ছে সকল কমান্ডগুলো একটি স্ক্রিপ্ট ফাইলে (script file) রাখা। আমি আমার ইনস্টলেশন স্ক্রিপ্টস (installation scripts) অর্গানাইজ (organize) করেছি ডিফল্ট রিপোজিটরিজ (default repositories) এর মধ্যে, যেগুলো আমার aptinstall.sh স্ক্রিপ্ট দিয়ে ইনস্টল হয়, এবং এক্সটার্নাল সোর্সেস (external sources) ইনভল্ভ (involve) করা প্রোগ্রামগুলো, যেগুলো আমার programs.sh স্ক্রিপ্ট দিয়ে হ্যান্ডেল (handled) হয়।

ডেস্কটপ এনভায়রনমেন্ট সেটআপ করা (Setting up the desktop environment)

আমি যখন নতুন ডেস্কটপ (fresh desktop) পেয়েছি (ইন্টেনশনালি বা অনইন্টেনশনালি) недавির সময়গুলোতে, আমি সবসময় লাগে ভুলে যাই কত সময় লাগে মনে করতে, খুঁজে বের করতে, এবং তারপর সব ডেস্কটপ এনভায়রনমেন্ট সেটিংস (desktop environment settings) চেঞ্জ করতে। কীবোর্ড শর্টকাটস (keyboard shortcuts), ওয়ার্কস্পেসেস (workspaces), সাউন্ড সেটিংস (sound settings), নাইট মোড (night mode)... ইট অ্যাডস আপ (it adds up)!

খুশির কথা, এই সকল সেটিংস কোথাও একটি নন-গ্রাফিক্যাল ফরম্যাটে (non-graphical format) সংরক্ষিত থাকতে হয়, মানে যদি আমরা জানি কীভাবে সেটি হয়, তবে আমরা সম্ভবত একটি উপায় খুঁজে পাবো সেটি সহজে ম্যানিপুলেট (manipulate) করার জন্য একটি বাশ স্ক্রিপ্ট (bash script) দিয়ে। লো অ্যান্ড বিহোল্ড (Lo and behold) টার্মিনাল কমান্ড, gsettings list-recursively।

GNOME ডেস্কটপ এনভায়রনমেন্টের (GNOME desktop environment) জন্য হেক অফ অ লট (heck of a lot) সেটিংস আছে। আমরা লিস্টটি ইজিয়ার (easier) করতে পারি স্ক্রোল থ্রু (scroll through) (যদি, আমার মত, আপনি কখনো কখনো সেই টাইপের পার্সন (type of person) হন যারা বলে "Just let me look at everything and figure out what I want!") পাইপ (pipe) করে less-এ: gsettings list-recursively | less। অথবা, যদি আমাদের একটি ইঙ্কলিং (inkling) থাকে আমরা কী খুঁজছি, তবে আমরা grep ব্যবহার করতে পারি: gsettings list-recursively | grep 'keyboard'।

আমরা আমাদের সেটিংস ম্যানিপুলেট (manipulate) করতে পারি gsettings set কমান্ড দিয়ে। কখনো কখনো আমাদের পছন্দের সেটিংটির সিনট্যাক্স (syntax) খুঁজে বের করা কঠিন হতে পারে, তাই যখন আমরা প্রথম আমাদের স্ক্রিপ্ট বানাচ্ছি, আমি রিকমেন্ড (recommend) করি GUI ব্যবহার করে পরিবর্তনগুলো করার জন্য, তারপর আমরা যে gsettings লাইনটি পরিবর্তন করলাম সেটি খুঁজে বের করুন এবং এর ভ্যালু (value) রেকর্ড (record) করুন।

কিছু ইনস্পিরেশন (inspiration) এর জন্য, আপনি আমার গিটহাবে desktop.sh সেটিংস স্ক্রিপ্ট দেখতে পারেন।

সবকিছু একসাথে রাখা (Putting it all together)

মডুলার স্ক্রিপ্টস (modular scripts) থাকা (সিমলিংকসের জন্য একটি, প্রোগ্রাম ইনস্টলের জন্য দুটি, ডেস্কটপ সেটিংসের জন্য একটি) উভয়ই উপযোগী चीজগুলো অর্গানাইজড (organized) রাখতে এবং পার্টিয়ালি (partially) অটোমেটেড সেটআপ রান করতে। উদাহরণস্বরূপ, যদি আমি একটি VPS সেটআপ করি যেখানে আমি শুধু কমান্ড লাইন ব্যবহার করি, তবে আমাকে গ্রাফিক্যাল প্রোগ্রামস বা ডেস্কটপ সেটিংস ইনস্টল করার চিন্তা করতে হবে না।

যেসব কেসে আমি সকল স্ক্রিপ্টস রান করতে চাই, তবে একে একে করা একটু টেডিয়াস (tedious)। ভাগ্যভরে, যেহেতু বাশ স্ক্রিপ্টস (bash scripts) নিজেরা টার্মিনাল কমান্ডস (terminal commands) দিয়ে রান করা যায়, আমরা শুধু একটি মাস্টার স্ক্রিপ্ট (master script) লিখতে পারি সেগুলো সকল রান করার জন্য!

এখানে আমার মাস্টার স্ক্রিপ্ট (master script) একটি নতুন উবুন্টু ডেস্কটপ মেশিনের সেটআপ হ্যান্ডেল (handle) করার জন্য:

#!/bin/bash ./symlink.sh ./aptinstall.sh ./programs.sh ./desktop.sh # Get all upgrades sudo apt upgrade -y # See our bash changes source ~/.bashrc # Fun hello figlet "... and we're back!" | lolcat

আপগ্রেড লাইনটি আমি ভালো মেজার (good measure) হিসেবে ফেললাম। এটি নিশ্চিত করবে যে আমাদের ফ্রেশ ডেস্কটপে ইনস্টল করা প্রোগ্রামগুলো লেটেস্ট আপডেটস (latest updates) পায়। এখন একটি সিঙ্গল, সিম্পল বাশ কমান্ড (bash command) সব কিছু হ্যান্ডেল করবে!

আপনি লক্ষ্য করতে পারেন যে, যদিও আমাদের ডেস্কটপ এখন ফ্যামিলিয়ারলি (familiarly) লুক এন্ড রান (look and run) করছে, এই স্ক্রিপ্টস এক খুব গুরুত্বপূর্ণ এরিয়া (area) কভার করে না: আমাদের ফাইলস। আশা করি, আপনার সেসব জন্য একটি ব্যাকআপ মেথড (backup method) আছে যেটি কোনো ফর্ম অফ রিলाएবল এক্সটার্নাল হার্ডওয়্যার (reliable external hardware) ইনভল্ভ করে। যদি না হয়, এবং আপনি আপনার কাজ এক্সটার্নাল রিপোজিটরি হোস্টস (external repository hosts) যেন গিটহাব (GitHub) বা গিটল্যাব (GitLab)-এ রাখতে থাকেন, তবে আমার একটি উপায় আছে আপনার গিটহাব রিপোজিটরিগুলো অটোমেটিক্যালি ক্লোন (clone) এবং ব্যাকআপ (back up) করার জন্য বাশ ওন-লাইনারস (Bash one-liners) দিয়ে।

এক্সটার্নাল রিপোজিটরি হোস্টস (external repository hosts) এ রিলাই (rely) করা ১০০% কভারেজ (coverage) অফার করে না, যাইহোক। যেসব ফাইল আপনি এক্সটার্নালি হোস্টেড রিপোজিটরিতে (externally hosted repository) (প্রাইভেট বা অন্যথা) রাখবেন না, সেগুলো কনসিকোয়েন্সিয়ালি (consequently) পুল (pull) করা যাবে না। গিট ইগ্নোরড অবজেক্টস (Git ignored objects) যেগুলো ইনক্লুডেড ফাইলস (included files) থেকে জেনারেট (generate) করা যাবে না, যেন প্রাইভেট কিজ (private keys) এবং সিক্রেটস (secrets), সেগুলো রিক্রিয়েট (recreate) হবে না। সেসব ফাইল, যাইহোক, সম্ভবত যথেষ্ট ছোট যে আপনি এক বানচ কাপলে (a whole bunch) ফিট (fit) করতে পারেন কয়েকটি এনক্রিপ্টেড (encrypted) USB ফ্ল্যাশ ড্রাইভসে (USB flash drives) (এবং আপনার যদি প্রাইভেট কি ব্যাকআপস (private key backups) না থাকে, হয়তো আপনাকে সেটি প্রথমে করতেই হবে?)।

সেটি বলা থাকলেও, আশা করি এই পোস্ট আপনাকে কমপক্ষে কিছু ইনস্পিরেশন (inspiration) দিয়েছে কীভাবে ডটফাইলস (dotfiles) এবং বাশ স্ক্রিপ্টস (bash scripts) একটি ফ্রেশ ডেস্কটপ সেটআপ অটোমেট করতে সাহায্য করতে পারে। আপনি যদি কিছু উপযোগী সেটিংস খুঁজে পান, দয়া করে অন্যদের সেগুলো আবিষ্কার করতে সাহায্য করুন আপনার ডটফাইলস শেয়ার (share) করে!

  1. KDE Connect ব্যবহার করে উবুন্টু ডেস্কটপে অ্যান্ড্রয়েড নোটিফিকেশন পাওয়ার পদ্ধতি

  2. জনপ্রিয় ডেস্কটপ এবং অনলাইন টুল ব্যবহার করে PDF এডিট করার উপায়

  3. Bash-it: স্ক্রিপ্ট, এলিয়াস ও কাস্টম ফাংশন পরিচালনার 궁극ের বাশ ফ্রেমওয়ার্ক

  4. উবুন্টু লিনাক্স আপডেট করা: ডেস্কটপ ও সার্ভারের জন্য ধাপে ধাপে গাইড