أتمتة المهام اليومية في نظام التشغيل (Linux/Windows) باستخدام مكتبة OS
ماذا سنتعلم؟ في هذا الدرس، سنتعلم كيفية استخدام مكتبة os في بايثون لأتمتة مهام نظام التشغيل الشائعة مثل إنشاء المجلدات، نقل الملفات، وتشغيل الأوامر.
سنتعلم اليوم كيفية بناء سكريبت بايثون بسيط لإدارة الملفات والمجلدات عبر أنظمة التشغيل المختلفة.
الخطوة 1: استيراد مكتبة OS وفهم أساسيات التعامل مع المسارات
تُعد مكتبة os (Operating System) جزءًا أساسيًا من بايثون، وتوفر واجهة للتفاعل مع نظام التشغيل الذي يعمل عليه السكريبت. هذا يجعل سكريبتاتك قابلة للنقل وتعمل على أنظمة مختلفة مثل Linux، Windows، و macOS دون الحاجة لتغييرات كبيرة.
import os # استيراد مكتبة OS للتعامل مع وظائف نظام التشغيل
# الحصول على المسار الحالي للعمل (المجلد الذي يتم تشغيل السكريبت منه)
current_directory = os.getcwd()
print(f"المسار الحالي للعمل: {current_directory}")
# بناء مسار ملف أو مجلد بشكل مستقل عن نظام التشغيل
# os.path.join() يتعامل مع الفواصل بين المجلدات بشكل صحيح لكل نظام تشغيل
file_name = "تقرير_المبيعات.txt"
# مثال: بناء مسار لملف داخل مجلد فرعي 'مجلد_جديد' داخل المسار الحالي
file_path_example = os.path.join(current_directory, "مجلد_جديد", file_name)
print(f"مثال على مسار مقترح للملف: {file_path_example}")
ملاحظة تقنية: مكتبةosتوفر واجهة للتفاعل مع نظام التشغيل الذي يعمل عليه السكريبت، مما يجعل الأتمتة ممكنة بغض النظر عن النظام (Linux, Windows, macOS). استخدامos.path.join()أمر بالغ الأهمية للحفاظ على قابلية نقل السكريبتات بين الأنظمة المختلفة.
الخطوة 2: إنشاء مجلدات وملفات برمجياً
تعتبر إدارة المجلدات والملفات من المهام الأساسية في الأتمتة. باستخدام os.makedirs()، يمكنك إنشاء مجلد واحد أو سلسلة من المجلدات المتداخلة دفعة واحدة، بينما يمكن إنشاء الملفات وكتابة البيانات فيها باستخدام دوال بايثون القياسية لفتح الملفات.
import os
# تحديد اسم المجلد الجديد الذي سيتم إنشاؤه
new_folder_name = "بيانات_التقارير"
# بناء المسار الكامل للمجلد الجديد داخل المسار الحالي
new_folder_path = os.path.join(os.getcwd(), new_folder_name)
# التحقق مما إذا كان المجلد موجوداً بالفعل قبل إنشائه لتجنب الأخطاء
if not os.path.exists(new_folder_path): # os.path.exists() تتحقق من وجود مسار ملف أو مجلد
os.makedirs(new_folder_path) # إنشاء المجلدات (بما في ذلك المجلدات الأبوية إذا لم تكن موجودة)
print(f"تم إنشاء المجلد: {new_folder_path}")
else:
print(f"المجلد موجود بالفعل: {new_folder_path}")
# إنشاء ملف نصي داخل المجلد الجديد الذي تم إنشاؤه
file_to_create = os.path.join(new_folder_path, "تقرير_يناير_2024.txt")
with open(file_to_create, "w", encoding="utf-8") as f: # فتح الملف في وضع الكتابة (w) مع دعم UTF-8
f.write("هذا هو تقرير شهر يناير لعام 2024.\n") # كتابة السطر الأول من المحتوى
f.write("يتضمن بيانات الأداء والملخصات الشهرية.") # كتابة السطر الثاني
print(f"تم إنشاء الملف: {file_to_create}")
ملاحظة تقنية: استخدامos.path.exists()قبل إنشاء المجلدات يمنع الأخطاء إذا كان المجلد موجوداً بالفعل، وهو ممارسة برمجية جيدة. المعاملwفيopen()يعني الكتابة، وإذا كان الملف موجوداً فسيتم مسح محتواه، وإذا لم يكن موجوداً فسيتم إنشاؤه.
الخطوة 3: نقل وإعادة تسمية الملفات
يمكنك بسهولة نقل الملفات بين المجلدات أو إعادة تسميتها باستخدام دالة os.rename(). هذه الدالة قوية بما يكفي للتعامل مع كلتا العمليتين بناءً على المسارات التي تقدمها.
import os
# تحديد المسار المصدر للملف الذي تم إنشاؤه في الخطوة السابقة
source_folder = os.path.join(os.getcwd(), "بيانات_التقارير")
source_file = os.path.join(source_folder, "تقرير_يناير_2024.txt")
# تحديد المجلد الوجهة الجديد للملف بعد النقل
destination_folder = os.path.join(os.getcwd(), "تقارير_مؤرشفة")
# تحديد المسار الكامل للملف في وجهته الجديدة مع اسم جديد
destination_file = os.path.join(destination_folder, "يناير_2024_مؤرشف.txt")
# التأكد من وجود المجلد الوجهة قبل محاولة نقل الملف إليه
if not os.path.exists(destination_folder): # التحقق من وجود مجلد الأرشفة
os.makedirs(destination_folder) # إنشاء مجلد الأرشفة إذا لم يكن موجوداً
print(f"تم إنشاء مجلد الأرشفة: {destination_folder}")
# التحقق من وجود الملف المصدر قبل محاولة نقله
if os.path.exists(source_file): # التأكد من أن الملف الذي نريد نقله موجود
os.rename(source_file, destination_file) # نقل الملف وإعادة تسميته في نفس العملية
print(f"تم نقل وإعادة تسمية الملف من '{source_file}' إلى '{destination_file}'")
else:
print(f"الملف المصدر غير موجود للنقل: {source_file}")
ملاحظة تقنية: os.rename() يستخدم لنقل الملفات وتغيير أسمائها. إذا كان المسار الوجهة في مجلد مختلف، فإنه يعمل كعملية نقل. إذا كان المسار الوجهة في نفس المجلد ولكن باسم مختلف، فإنه يعمل كعملية إعادة تسمية.
الخطوة 4: تشغيل أوامر النظام
لأتمتة المهام المعقدة أو التفاعل مع أدوات سطر الأوامر الأخرى، يمكنك استخدام os.system() لتشغيل أي أمر يمكن تشغيله مباشرة في سطر الأوامر الخاص بنظام التشغيل. هذا يفتح الباب لأتمتة واسعة النطاق.
import os
print("\n--- تشغيل أوامر النظام ---")
# تحديد الأمر المناسب لعرض محتويات المجلد الحالي بناءً على نظام التشغيل
if os.name == 'nt': # 'nt' يشير إلى نظام التشغيل Windows
command_to_run = "dir"
print("نظام التشغيل: Windows")
else: # أنظمة التشغيل الشبيهة بـ Unix (مثل Linux و macOS)
command_to_run = "ls -l"
print("نظام التشغيل: Linux/macOS")
print(f"تنفيذ الأمر: '{command_to_run}' لعرض محتويات المجلد الحالي:")
os.system(command_to_run) # تنفيذ الأمر وعرض نتيجته مباشرة في الطرفية
# مثال آخر: فتح برنامج (هذا الجزء اختياري وقد يتطلب تعديلاً)
# يمكن استخدام os.system() لفتح تطبيقات، ولكن يجب توخي الحذر
# لأن هذه العملية قد تعلق السكريبت أو تتطلب تدخل المستخدم.
# if os.name == 'nt':
# print("\nمحاولة فتح المفكرة (notepad.exe) على Windows...")
# os.system("notepad.exe")
# else:
# print("\nيمكنك محاولة تشغيل 'gedit' أو 'nano' على Linux/macOS إذا كانت مثبتة.")
# # os.system("gedit") # يتطلب تثبيت gedit
ملاحظة تقنية: os.system() يسمح بتنفيذ أوامر سطر الأوامر مباشرة من بايثون، مما يفتح الباب لأتمتة واسعة النطاق لأي أمر يمكن تشغيله يدوياً. ومع ذلك، كن حذرًا عند استخدامه مع مدخلات المستخدم لتجنب ثغرات حقن الأوامر.
الكود النهائي الكامل
إليك السكريبت كاملاً، يجمع جميع الخطوات التي تعلمناها لأتمتة إنشاء المجلدات والملفات، نقلها، وتشغيل أمر نظام بسيط.
import os
import time # لإضافة تأخير بسيط لمشاهدة الخطوات بشكل أوضح
print("--- بدء سكريبت أتمتة المهام اليومية ---")
# الخطوة 1: فهم المسارات والمسار الحالي
current_directory = os.getcwd()
print(f"\n1. المسار الحالي للعمل: {current_directory}")
file_name_example = "تقرير_المبيعات.txt"
file_path_example = os.path.join(current_directory, "مجلد_جديد", file_name_example)
print(f" مثال على مسار مقترح للملف: {file_path_example}")
time.sleep(1)
# الخطوة 2: إنشاء مجلدات وملفات برمجياً
new_folder_name = "بيانات_التقارير"
new_folder_path = os.path.join(current_directory, new_folder_name)
print(f"\n2. التحقق وإنشاء المجلد '{new_folder_name}'...")
if not os.path.exists(new_folder_path):
os.makedirs(new_folder_path)
print(f" تم إنشاء المجلد: {new_folder_path}")
else:
print(f" المجلد موجود بالفعل: {new_folder_path}")
file_to_create = os.path.join(new_folder_path, "تقرير_يناير_2024.txt")
with open(file_to_create, "w", encoding="utf-8") as f:
f.write("هذا هو تقرير شهر يناير لعام 2024.\n")
f.write("يتضمن بيانات الأداء والملخصات الشهرية.")
print(f" تم إنشاء الملف: {file_to_create}")
time.sleep(1)
# الخطوة 3: نقل وإعادة تسمية الملفات
source_file = os.path.join(new_folder_path, "تقرير_يناير_2024.txt")
destination_folder = os.path.join(current_directory, "تقارير_مؤرشفة")
destination_file = os.path.join(destination_folder, "يناير_2024_مؤرشف.txt")
print(f"\n3. التحقق وإنشاء مجلد الأرشفة '{os.path.basename(destination_folder)}'...")
if not os.path.exists(destination_folder):
os.makedirs(destination_folder)
print(f" تم إنشاء مجلد الأرشفة: {destination_folder}")
else:
print(f" مجلد الأرشفة موجود بالفعل: {destination_folder}")
print(f" محاولة نقل الملف '{os.path.basename(source_file)}'...")
if os.path.exists(source_file):
os.rename(source_file, destination_file)
print(f" تم نقل وإعادة تسمية الملف من '{source_file}' إلى '{destination_file}'")
else:
print(f" الملف المصدر غير موجود للنقل: {source_file}")
time.sleep(1)
# الخطوة 4: تشغيل أوامر النظام
print("\n4. تشغيل أمر نظام لعرض محتويات المجلد الحالي...")
if os.name == 'nt':
command_to_run = "dir"
print(" نظام التشغيل: Windows")
else:
command_to_run = "ls -l"
print(" نظام التشغيل: Linux/macOS")
print(f" تنفيذ الأمر: '{command_to_run}'")
os.system(command_to_run)
print("\n--- انتهى سكريبت أتمتة المهام اليومية ---")
# لتنظيف المجلدات والملفات التي تم إنشاؤها (اختياري)
# print("\nتنظيف المجلدات والملفات (اختياري)...\n")
# if os.path.exists(destination_file): # حذف الملف المؤرشف
# os.remove(destination_file)
# print(f"تم حذف الملف: {destination_file}")
# if os.path.exists(destination_folder): # حذف مجلد الأرشفة (يجب أن يكون فارغاً)
# os.rmdir(destination_folder)
# print(f"تم حذف المجلد: {destination_folder}")
# if os.path.exists(new_folder_path): # حذف مجلد البيانات (يجب أن يكون فارغاً)
# os.rmdir(new_folder_path)
# print(f"تم حذف المجلد: {new_folder_path}")
النتيجة المتوقعة
عند تشغيل السكريبت، ستلاحظ سلسلة من الإجراءات والرسائل المطبوعة في الطرفية (Terminal/Command Prompt) والتي توضح تقدم الأتمتة:
- سيتم طباعة المسار الحالي للعمل ومثال على كيفية بناء مسار ملف.
- سيقوم السكريبت بإنشاء مجلد جديد باسم
بيانات_التقاريرفي المسار الحالي إذا لم يكن موجودًا بالفعل. - سيتم إنشاء ملف نصي باسم
تقرير_يناير_2024.txtداخل مجلدبيانات_التقارير. - سيقوم السكريبت بإنشاء مجلد آخر باسم
تقارير_مؤرشفةإذا لم يكن موجودًا. - سيتم نقل ملف
تقرير_يناير_2024.txtمنبيانات_التقاريرإلىتقارير_مؤرشفةوإعادة تسميته إلىيناير_2024_مؤرشف.txt. - أخيرًا، سيتم تنفيذ أمر سطر أوامر خاص بنظام التشغيل (
dirعلى Windows أوls -lعلى Linux/macOS) لعرض محتويات المجلد الحالي، مما يؤكد إنشاء المجلدات الجديدة (أو وجودها) وحركة الملفات.
ستظهر رسائل تأكيد لكل خطوة، مثل "تم إنشاء المجلد: ..." و "تم نقل وإعادة تسمية الملف...".