مقالات مختارة

تشغيل أوامر النظام من بايثون باستخدام subprocess.run | بايثون بعد الأساسيات 15

تشغيل أوامر النظام من بايثون باستخدام subprocess.run مع CMD وPowerShell وLinux وقراءة stdout وstderr

تحتاج أحيانًا إلى أن يشغّل برنامج بايثون أمرًا من أوامر النظام، أو يفتح برنامجًا خارجيًا، أو ينفذ أداة مثل git أو ffmpeg ثم يقرأ النتيجة ويتعامل مع نجاح الأمر أو فشله. الطريقة الحديثة والمباشرة لهذه المهمة هي مكتبة subprocess المدمجة مع بايثون، وبالأخص الدالة subprocess.run().

في هذا الدرس سنبدأ بأبسط مثال يعمل على Windows وLinux وmacOS، ثم ننتقل إلى التقاط stdout وstderr، واستخدام check=True وtimeout، وتشغيل CMD وPowerShell وأوامر Linux، ثم نختم بالفرق بين shell=False وshell=True ولماذا يؤثر ذلك في الأمان.

الخلاصة السريعة: إذا أردت تشغيل برنامج خارجي وانتظار انتهائه، فابدأ عادةً بـ subprocess.run() ومرّر الأمر كقائمة مثل ["program", "arg"]. استخدم capture_output=True لقراءة المخرجات، وtext=True للحصول عليها كنص، وcheck=True لتحويل فشل الأمر إلى Exception واضحة.

تحميل مشروع Safe Command Runner

حمّل كود المشروع الكامل، وملفات runner.py وapp.py، والاختبارات التلقائية؛ وجرّب أمثلة subprocess.run() وstdout وstderr وtimeout بنفسك.

تحميل ملفات المشروع ZIP

هذا الدرس مناسب لسلسلة بايثون بعد الأساسيات. إذا كان هدفك مختلفًا وتريد تشغيل ملف .py يدويًا من CMD أو PowerShell، فراجع دليل تشغيل ملف Python من CMD وTerminal وVS Code. هنا سنفعل العكس: برنامج Python هو الذي سيشغّل أمرًا أو برنامجًا خارجيًا.

ما هي مكتبة subprocess في بايثون؟

مكتبة subprocess جزء من المكتبة القياسية في بايثون، لذلك لا تحتاج إلى تثبيتها عبر pip. وظيفتها إنشاء Processes جديدة، والاتصال بمدخلاتها ومخرجاتها وأخطاءها، والحصول على رمز الخروج return code.

توصي وثائق Python الحالية باستخدام subprocess.run() للحالات التي تستطيع التعامل معها، والانتقال إلى Popen عندما تحتاج تحكمًا أكثر تقدمًا في Process طويلة التشغيل أو تدفق المخرجات أثناء التنفيذ.

المرجع الرسمي: Python Documentation — subprocess.

ملاحظة مهمة: subprocess تعتمد على تشغيل Processes حقيقية في نظام التشغيل. وفق توثيق Python فهي غير مدعومة على Android وiOS وWASI، ولذلك لا تتوقع أن تعمل بالطريقة نفسها داخل بعض بيئات Python التي تعمل في المتصفح أو WebAssembly. إذا كنت تجرب أمثلة بسيطة أونلاين، راجع تشغيل بايثون أونلاين بدون تثبيت لمعرفة حدود بيئات المتصفح.

أول مثال: تشغيل أمر من بايثون باستخدام subprocess.run

بدل الاعتماد على أمر يختلف بين Windows وLinux، سنستخدم مفسر Python الحالي نفسه. يوفر sys.executable مسار المفسر الذي يشغل السكربت الآن:

import subprocess
import sys

result = subprocess.run(
    [sys.executable, "--version"]
)

print("Return code:", result.returncode)

قد ترى الناتج هكذا:

Python 3.15.2
Return code: 0

رقم 0 يعني عادةً أن البرنامج الخارجي انتهى بنجاح. أما الرقم غير الصفري فيشير عادةً إلى أن الأمر فشل أو انتهى بحالة خطأ يحددها البرنامج الذي شغلته.

لماذا نمرر الأمر كقائمة بدل String؟

الأسلوب المفضل في الحالات العادية هو تمرير اسم البرنامج وكل Argument كعنصر منفصل:

subprocess.run(
    [sys.executable, "-c", "print('Hello from child process')"]
)

هنا العناصر الثلاثة واضحة:

  • sys.executable: البرنامج الذي سنشغله.
  • -c: خيار يطلب من Python تنفيذ نص كود.
  • print(...): القيمة التي سيستقبلها الخيار.

هذا الأسلوب يقلل الحاجة إلى تفسير Shell للنص، ويجعل التعامل مع Arguments التي تحتوي مسافات أكثر وضوحًا. توصي وثائق Popen بتمرير args كسلسلة من القيم ما لم تكن لديك حاجة محددة إلى String.

ما الذي تعيده subprocess.run؟ شرح CompletedProcess

لا تعيد run() مجرد True أو False. إنها تعيد كائنًا من النوع CompletedProcess يحتوي معلومات عن الأمر بعد انتهائه.

import subprocess
import sys

result = subprocess.run(
    [sys.executable, "-c", "print('done')"]
)

print(type(result).__name__)
print(result.args)
print(result.returncode)

أهم الخصائص التي سنستخدمها في المقال:

الخاصيةماذا تحتوي؟
argsالأمر وArguments التي شُغلت.
returncodeرمز خروج العملية.
stdoutالناتج القياسي إذا طلبت التقاطه.
stderrرسائل الخطأ القياسية إذا طلبت التقاطها.

التقاط مخرجات الأمر باستخدام capture_output=True

في الأمثلة السابقة خرجت النتيجة مباشرة إلى Terminal. إذا أردت أن يستخدم برنامجك الناتج، أضف capture_output=True:

import subprocess
import sys

result = subprocess.run(
    [
        sys.executable,
        "-c",
        "print('Arab Python')",
    ],
    capture_output=True,
)

print(result.stdout)
print(result.stderr)

بدون text=True ستكون البيانات الملتقطة عادةً من نوع bytes:

b'Arab Python\n'
b''
التقاط stdout وstderr في بايثون باستخدام subprocess.run مع capture_output وtext لقراءة مخرجات الأوامر

استخدام text=True للحصول على String بدل bytes

في معظم البرامج التعليمية والتطبيقات النصية تريد التعامل مع الناتج كسلسلة نصية عادية. أضف text=True:

import subprocess
import sys

result = subprocess.run(
    [
        sys.executable,
        "-c",
        "print('Arab Python')",
    ],
    capture_output=True,
    text=True,
)

print(result.stdout)
print(type(result.stdout).__name__)

الناتج:

Arab Python
str

الخيار text=True هو الاسم الأكثر وضوحًا للخيار القديم universal_newlines=True. وإذا كنت تحتاج ترميزًا محددًا تستطيع استخدام encoding=... أيضًا.

الفرق بين stdout وstderr

البرنامج الخارجي قد يكتب النتيجة الطبيعية في stdout، ويكتب التشخيص أو الخطأ في stderr. يمكن التقاط الاثنين معًا ثم اتخاذ قرار داخل Python.

import subprocess
import sys

code = (
    "import sys; "
    "print('normal output'); "
    "print('error output', file=sys.stderr)"
)

result = subprocess.run(
    [sys.executable, "-c", code],
    capture_output=True,
    text=True,
)

print("STDOUT:", result.stdout.strip())
print("STDERR:", result.stderr.strip())

الناتج:

STDOUT: normal output
STDERR: error output

هذه النقطة مهمة عند تشغيل أدوات حقيقية: لا تفترض أن كل ما يظهر في Terminal موجود داخل stdout.

فحص returncode بدل افتراض نجاح الأمر

إذا كان check=False — وهو الافتراضي — فلن ترفع run() استثناء لمجرد أن البرنامج أعاد رمزًا غير صفري. لذلك تستطيع فحص returncode بنفسك:

import subprocess
import sys

result = subprocess.run(
    [
        sys.executable,
        "-c",
        "raise SystemExit(3)",
    ]
)

if result.returncode == 0:
    print("نجح الأمر")
else:
    print("فشل الأمر:", result.returncode)

الناتج:

فشل الأمر: 3

استخدام check=True وCalledProcessError

في كثير من البرامج لا تريد متابعة التنفيذ وكأن كل شيء نجح. عند استخدام check=True ترفع subprocess.run() الخطأ CalledProcessError إذا انتهت العملية برمز غير صفري.

import subprocess
import sys

try:
    subprocess.run(
        [
            sys.executable,
            "-c",
            "raise SystemExit(3)",
        ],
        check=True,
    )
except subprocess.CalledProcessError as error:
    print("فشل الأمر")
    print("Return code:", error.returncode)

إذا كنت تحتاج مراجعة أساس التعامل مع الاستثناءات، راجع شرح try وexcept والتعامل مع الأخطاء في بايثون.

الحصول على stdout وstderr عند الفشل

ادمج check=True مع capture_output=True وtext=True:

import subprocess
import sys

code = (
    "import sys; "
    "print('details', file=sys.stderr); "
    "raise SystemExit(2)"
)

try:
    subprocess.run(
        [sys.executable, "-c", code],
        capture_output=True,
        text=True,
        check=True,
    )
except subprocess.CalledProcessError as error:
    print("code:", error.returncode)
    print("stderr:", error.stderr.strip())
معالجة CalledProcessError وTimeoutExpired في بايثون باستخدام check وtimeout مع subprocess.run

منع الأمر من التعليق باستخدام timeout

قد يتوقف برنامج خارجي أو ينتظر موردًا وقتًا طويلًا. ضع حدًا زمنيًا باستخدام timeout:

import subprocess
import sys

try:
    subprocess.run(
        [
            sys.executable,
            "-c",
            "import time; time.sleep(5)",
        ],
        timeout=1,
    )
except subprocess.TimeoutExpired:
    print("انتهت المهلة قبل اكتمال الأمر")

عند انتهاء المهلة ترفع الدالة TimeoutExpired. ووفق التوثيق، في run() يتم قتل العملية ثم انتظارها قبل إعادة رفع الاستثناء، مع ملاحظة أن إنشاء Process نفسها قد لا يكون قابلًا للمقاطعة فورًا على بعض منصات النظام.

تشغيل الأمر داخل مجلد معين باستخدام cwd

الخيار cwd يحدد Current Working Directory للعملية الجديدة. المثال التالي يجعل Process الطفل تطبع المجلد الذي تعمل بداخله:

from pathlib import Path
import subprocess
import sys

project_dir = Path.cwd()

result = subprocess.run(
    [
        sys.executable,
        "-c",
        "import os; print(os.getcwd())",
    ],
    cwd=project_dir,
    capture_output=True,
    text=True,
    check=True,
)

print(result.stdout.strip())

هذا مفيد عندما تشغل أداة تتوقع ملفات إعداد أو مسارات نسبية داخل مجلد مشروع محدد.

تمرير Environment Variables باستخدام env

إذا مررت env فإنك تحدد بيئة العملية الجديدة بدل الاعتماد مباشرة على الوراثة الافتراضية. في التطبيقات المعتادة، خذ نسخة من os.environ ثم عدّل ما تحتاجه:

import os
import subprocess
import sys

child_env = os.environ.copy()
child_env["APP_MODE"] = "demo"

result = subprocess.run(
    [
        sys.executable,
        "-c",
        "import os; print(os.getenv('APP_MODE'))",
    ],
    env=child_env,
    capture_output=True,
    text=True,
    check=True,
)

print(result.stdout.strip())

الناتج:

demo

إذا كانت إعداداتك محفوظة في ملف .env، راجع أيضًا حفظ مفاتيح API باستخدام .env وpython-dotenv. تذكر أن env في subprocess لا يقرأ ملف .env بنفسه؛ أنت تمرر له Mapping للمتغيرات.

إرسال نص إلى stdin باستخدام input

يمكنك تمرير قيمة إلى المدخل القياسي للعملية الجديدة عبر input=.... مع text=True تستطيع إرسال String مباشرة:

import subprocess
import sys

child_code = (
    "name = input(); "
    "print(name.upper())"
)

result = subprocess.run(
    [sys.executable, "-c", child_code],
    input="arab python\n",
    capture_output=True,
    text=True,
    check=True,
)

print(result.stdout.strip())

الناتج:

ARAB PYTHON

تشغيل برنامج خارجي من بايثون

الفكرة نفسها لا تقتصر على أوامر النظام. تستطيع تشغيل أي Executable متاح على الجهاز. مثلًا، إذا كان Git مثبتًا:

import subprocess

result = subprocess.run(
    ["git", "--version"],
    capture_output=True,
    text=True,
    check=True,
)

print(result.stdout.strip())

إذا لم يكن البرنامج موجودًا أو لا يستطيع النظام العثور عليه، فقد تحصل على FileNotFoundError. للتشخيص يمكنك استخدام shutil.which():

from shutil import which

git_path = which("git")

if git_path is None:
    print("Git غير موجود في PATH")
else:
    print(git_path)

عند تشغيل مفسر Python نفسه من داخل سكربت Python، استخدم sys.executable بدل كتابة python أو python3 عشوائيًا. توثيق subprocess يوصي بهذه الطريقة لأنها تشير إلى المفسر الحالي فعليًا.

تشغيل أوامر CMD من بايثون على Windows

بعض أوامر CMD مثل dir هي أوامر داخلية في Shell وليست ملفات تنفيذية مستقلة. تستطيع تشغيلها بصورة صريحة عبر cmd /c:

import subprocess

result = subprocess.run(
    ["cmd", "/c", "dir"],
    capture_output=True,
    text=True,
    check=True,
)

print(result.stdout)

هذا المثال مخصص لـWindows. الخيار /c يعني تنفيذ الأمر ثم إنهاء CMD.

تشغيل PowerShell من بايثون

على Windows تستطيع استدعاء Windows PowerShell هكذا:

import subprocess

result = subprocess.run(
    [
        "powershell",
        "-NoProfile",
        "-Command",
        "Get-Date",
    ],
    capture_output=True,
    text=True,
    check=True,
)

print(result.stdout.strip())

إذا كنت تستخدم PowerShell 7 فقد يكون اسم البرنامج pwsh بدل powershell. تحقق أولًا من البرنامج المثبت على جهازك.

تشغيل أوامر Linux وmacOS من بايثون

على أنظمة Unix-like تستطيع تشغيل برنامج مستقل مثل uname مباشرة:

import subprocess

result = subprocess.run(
    ["uname", "-a"],
    capture_output=True,
    text=True,
    check=True,
)

print(result.stdout.strip())

ويمكن تشغيل ls مثلًا:

subprocess.run(
    ["ls", "-la"],
    check=True,
)

هذه الأمثلة ليست متطابقة مع Windows لأن أسماء البرامج والـShell built-ins تختلف حسب النظام.

shell=False مقابل shell=True

القيمة الافتراضية هي shell=False، وهذا يعني أن Python لا يختار Shell تلقائيًا لتفسير النص. في معظم الحالات هذا هو الخيار الذي تبدأ به.

الحالةالاختيار الأنسب غالبًا
تشغيل برنامج مع Argumentsshell=False وتمرير قائمة.
تشغيل Python أو Git أو ffmpegshell=False.
تحتاج ميزة خاصة بالـShell مثل Pipeline أو Redirectionقد تحتاج shell=True أو بناء Pipeline باستخدام Processes منفصلة.
الأمر يحتوي مدخلًا غير موثوق من المستخدمتجنب تركيب String وتشغيلها بـshell=True.

مثال shell=True لأمر ثابت وموثوق

import subprocess

subprocess.run(
    "echo Hello",
    shell=True,
    check=True,
)

هذا المثال بسيط، لكن لا تجعل shell=True الخيار الافتراضي لمجرد أنه يسمح بكتابة الأمر كسطر واحد.

لماذا قد يكون shell=True خطرًا؟

عندما تطلب من Shell تفسير نص، تصبح الرموز الخاصة بالـShell ذات معنى. إذا ركبت النص من إدخال غير موثوق فقد يتحول جزء من البيانات إلى Command إضافية.

هذا مثال يجب تجنبه عندما تأتي القيمة من مستخدم:

import subprocess

user_value = input("اكتب اسمًا: ")

subprocess.run(
    f"echo {user_value}",
    shell=True,
)

الأفضل عندما لا تحتاج ميزات الـShell أن تمرر كل Argument كعنصر مستقل:

import subprocess

user_value = input("اكتب اسمًا: ")

subprocess.run(
    ["echo", user_value],
    check=True,
)
الفرق بين shell False وshell True في subprocess ومخاطر Command Injection عند تمرير المدخلات في بايثون

تقول وثائق Python إن subprocess لا تستدعي System Shell ضمنيًا. لكن إذا فعّلت shell=True تصبح مسؤولًا عن التعامل الصحيح مع المسافات والرموز الخاصة لتجنب Shell Injection. توجد تفاصيل إضافية خاصة بملفات .bat و.cmd على Windows، لذلك ارجع إلى قسم Security Considerations في التوثيق عند بناء برنامج يستقبل مدخلات غير موثوقة.

مرجع رسمي: Security Considerations — subprocess.

subprocess.run أم os.system؟

يمكنك رؤية كود قديم أو أمثلة قصيرة تستخدم:

import os

os.system("python --version")

os.system() تشغّل String داخل subshell، وقيمة الإرجاع ذات معنى يعتمد على النظام، كما أن التقاط الناتج والتعامل المنظم مع stdout وstderr وTimeouts أصعب.

في المقابل توفر subprocess.run() واجهة أوضح:

import subprocess
import sys

result = subprocess.run(
    [sys.executable, "--version"],
    capture_output=True,
    text=True,
    check=True,
)

print(result.stdout or result.stderr)

ولهذا توضح وثائق Python أن subprocess صممت لاستبدال عدد من الواجهات الأقدم مثل os.system. راجع أيضًا توثيق os.system الرسمي.

subprocess.run أم Popen؟

ابدأ بـrun() عندما تريد تشغيل أمر وانتظار نهايته. انتقل إلى Popen عندما تحتاج إدارة Process بصورة أكثر تقدمًا، مثل قراءة المخرجات أثناء استمرار البرنامج أو التحكم في Process طويلة التشغيل.

الحاجةrun()Popen
تشغيل أمر وانتظار انتهائهمناسب جدًاممكن لكن أكثر تعقيدًا
التقاط الناتج بعد النهايةمباشرممكن
Timeout بسيطمباشرممكن
قراءة Streaming أثناء التشغيلليس الاستخدام الأساسيأنسب
تحكم تفصيلي في Processمحدودأنسب

مشروع عملي: Safe Command Runner

سنحوّل الأفكار السابقة إلى دالة صغيرة تشغّل Arguments بدون Shell، وتلتقط المخرجات، وتحدد Timeout، وتسمح بتمرير متغيرات بيئة إضافية.

from dataclasses import dataclass
from pathlib import Path
from collections.abc import Mapping, Sequence
import os
import subprocess


@dataclass(slots=True)
class CommandResult:
    args: tuple[str, ...]
    returncode: int
    stdout: str
    stderr: str


def run_command(
    args: Sequence[str],
    *,
    timeout: float = 10,
    cwd: str | Path | None = None,
    env: Mapping[str, str] | None = None,
    check: bool = False,
) -> CommandResult:
    if isinstance(args, (str, bytes)):
        raise TypeError("مرر الأمر كقائمة أو Sequence من النصوص")

    child_env = os.environ.copy()

    if env:
        child_env.update(env)

    completed = subprocess.run(
        list(args),
        capture_output=True,
        text=True,
        shell=False,
        timeout=timeout,
        cwd=cwd,
        env=child_env,
        check=check,
    )

    return CommandResult(
        args=tuple(str(item) for item in completed.args),
        returncode=completed.returncode,
        stdout=completed.stdout,
        stderr=completed.stderr,
    )

ثم استخدمها هكذا:

import sys

result = run_command(
    [
        sys.executable,
        "-c",
        "print('Hello from subprocess')",
    ],
    check=True,
)

print(result.stdout.strip())

هذه الدالة لا تحاول دعم shell=True أصلًا؛ هدفها أن تكون Wrapper بسيطة للحالات المعتادة والآمنة افتراضيًا. ستجد المشروع الكامل والاختبارات داخل ملف ZIP المرفق مع الدرس.

أخطاء شائعة عند استخدام subprocess

1. كتابة أمر كامل كسلسلة ثم توقع أن يعمل بدون shell=True

الكود التالي لا يعني دائمًا ما تتوقعه:

subprocess.run(
    "python --version"
)

عند shell=False الأفضل تمرير Arguments منفصلة:

subprocess.run(
    ["python", "--version"]
)

ولتشغيل نفس المفسر الحالي بصورة أكثر موثوقية استخدم sys.executable.

2. نسيان capture_output ثم محاولة قراءة stdout

إذا لم تطلب التقاط الناتج، فقد تكون result.stdout تساوي None.

3. استخدام capture_output=True مع stdout أو stderr يدويًا

capture_output=True يضبط stdout وstderr إلى Pipes داخليًا؛ لا تجمعه مع قيم stdout=... أو stderr=... في الاستدعاء نفسه.

4. الاعتماد على returncode بدون فحصه

الأمر قد يفشل بينما يستمر برنامجك إذا بقي check=False. افحص returncode أو استخدم check=True عندما تريد اعتبار الفشل Exception.

5. عدم وضع timeout لأداة قد تعلق

إذا كنت تشغل برنامجًا خارجيًا يمكن أن ينتظر شبكة أو ملفًا أو Input، ضع Timeout مناسبًا وتوقع TimeoutExpired.

6. استخدام shell=True مع مدخل المستخدم

هذه من أهم الأخطاء. إذا لم تكن بحاجة فعلية إلى Shell فلا تستخدمها. وإذا احتجتها، لا تركّب Command من بيانات غير موثوقة دون قواعد escaping مناسبة للنظام.

7. افتراض أن أسماء الأوامر واحدة على كل الأنظمة

dir وcmd مرتبطة بـWindows، بينما ls وuname شائعة في Linux/macOS. اختر أمثلة تناسب النظام أو استخدم برنامجًا مشتركًا مثل sys.executable.

متى تستخدم subprocess في مشروع حقيقي؟

  • تشغيل أدوات خارجية مثل Git أو ffmpeg أو أدوات البناء.
  • تنفيذ سكربت أو برنامج آخر كجزء من Automation.
  • قراءة stdout لاستخراج نتيجة من أداة CLI.
  • تشغيل أوامر صيانة أو Build داخل مشروع تطوير.
  • دمج برنامج Python مع أدوات نظام موجودة أصلًا.

أما إذا كنت تريد بناء برنامج CLI يستقبل Arguments من المستخدم، فهذا موضوع مختلف؛ راجع بناء برنامج سطر أوامر CLI باستخدام argparse.

ملخص سريع لأهم خيارات subprocess.run

الخياراستخدامه
capture_output=Trueالتقاط stdout وstderr.
text=Trueالتعامل مع Streams كنصوص بدل bytes.
check=Trueرفع CalledProcessError عند رمز خروج غير صفري.
timeout=...منع الانتظار غير المحدود.
cwd=...تغيير مجلد العمل للعملية الجديدة.
env=...تحديد Environment للعملية الجديدة.
input=...إرسال بيانات إلى stdin.
shell=Trueتشغيل الأمر عبر Shell عندما تحتاج ميزاتها، مع اعتبارات أمان إضافية.

مصادر رسمية وروابط مكملة

الأسئلة الشائعة عن تشغيل أوامر النظام من بايثون

كيف أشغّل أمر نظام من بايثون؟

استخدم subprocess.run() ومرر اسم البرنامج وArguments في قائمة، مثل subprocess.run(["git", "--version"]). للحالات التي تريد فيها نفس مفسر Python الحالي استخدم sys.executable.

كيف أقرأ ناتج الأمر داخل بايثون؟

استخدم capture_output=True لالتقاط stdout وstderr، وأضف text=True إذا أردت Strings بدل bytes.

ما فائدة check=True في subprocess.run؟

تجعل run() ترفع CalledProcessError عندما ينتهي الأمر برمز غير صفري، بدل أن تحتاج إلى فحص returncode يدويًا في كل مرة.

كيف أحدد وقتًا أقصى لتنفيذ الأمر؟

استخدم timeout مثل timeout=5. إذا تجاوزت العملية المهلة ترفع بايثون TimeoutExpired.

ما الفرق بين subprocess.run وos.system؟

subprocess.run() توفر تحكمًا أوضح في Arguments والمخرجات والأخطاء والمهلة والبيئة، بينما os.system() تشغّل String داخل subshell وتملك واجهة أقدم وأقل مرونة لهذه الحالات.

ما الفرق بين subprocess.run وPopen؟

استخدم run() عندما تريد تشغيل أمر وانتظار انتهائه. استخدم Popen عندما تحتاج إدارة Process أثناء استمرارها أو Streaming للمخرجات أو تحكمًا أكثر تقدمًا.

هل shell=True ضروري لتشغيل الأوامر؟

لا. في معظم الحالات تستطيع تشغيل البرنامج مباشرة مع shell=False. تحتاج shell=True فقط عندما تعتمد فعليًا على ميزات Shell، ومعها يجب الانتباه إلى مخاطر Shell Injection.

كيف أشغّل CMD من بايثون؟

على Windows يمكنك تشغيل أمر داخلي في CMD عبر ["cmd", "/c", "الأمر"]. أما البرامج التنفيذية المستقلة فيمكن استدعاؤها مباشرة بدون CMD غالبًا.

كيف أشغّل PowerShell من بايثون؟

شغّل powershell أو pwsh كبرنامج خارجي، ثم مرر -Command والأمر المطلوب ضمن قائمة Arguments.

لماذا يظهر FileNotFoundError عند استخدام subprocess؟

غالبًا لأن البرنامج الذي تحاول تشغيله غير موجود أو غير متاح عبر PATH. استخدم shutil.which() للتحقق، أو مرر مسارًا كاملًا للبرنامج عند الحاجة.

هل تعمل subprocess داخل محرر Python أونلاين؟

ليس بالضرورة. المكتبة تعتمد على قدرة البيئة على إنشاء Processes حقيقية، وهي غير مدعومة في منصات مثل WASI وبعض بيئات الهاتف. لذلك اختبر هذه الأمثلة على Python محلي على نظام تشغيل يدعمها.

Admin
Admin
تعليقات