سيطرة السلطة الرئيسية: تقنيات السطر الأمري والنصوصية

هناك العديد من الأسباب لإيقاف تنفيذ السكربت. ربما يحتاج السكربت إلى الانتظار لاستلام إدخال المستخدم، أو بطء سرعة التنفيذ، أو الانتظار حتى ينتهي عمل آخر قبل المضي قدمًا. كما هو الحال مع معظم المهام في PowerShell، هناك أكثر من وسيلة لإيقاف تنفيذ السكربت. وتعتمد الطريقة التي تختارها على ما تحاول تحقيقه، وستكون لكل طريقة مزاياها وعيوبها. وتضيف تعقيدًا آخر إلى الخيارات المتاحة القدرة الجديدة لـ PowerShell على التشغيل عبر المنصات المتعددة. نظرًا لأن PowerShell يُستخدم في كثير من الأحيان كطريقة لربط تقنيات مختلفة معًا، تمامًا كما هو الحال في نظام التشغيل Windows، فإن هناك خيارات لإيقاف التنفيذ في سطر الأوامر لينكس يمكن دمجها في PowerShell أيضًا.

طرق إيقاف التنفيذ في PowerShell

ما هي الطرق المختلفة لإيقاف تنفيذ السكربت؟ في هذا المقال، سنقوم بتحليل القدرة على التوقف إما إلى أوامر النظام الأصلية وغير الأصلية. بالنسبة للأوامر الأصلية، نشير إلى تلك الأوامر التي تعتبر PowerShell أو .NET وظائف أو طرقًا مدمجة. تُعرف الطرق غير الأصلية بأنها برامج محددة لنظامي التشغيل Windows ولينكس يمكن استخدامها بالتزامن مع PowerShell.

طرق أصلية

  • Start-Sleep
  • [System.Threading.Thread]::Sleep()
  • Read-Host
  • [Console]::ReadKey()
  • $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")

طرق غير أصلية

Windows

  • pause
  • timeout

Linux

  • sleep
  • read -p

كما يمكنك ملاحظة، هناك عدة خيارات مختلفة، كل منها له فوائد وعيوبه. الخيار الذي تختاره سيؤثر في كيفية إيقاف التنفيذ وما هي التأثيرات الأخرى التي قد تحدث مع هذا الإيقاف.

الطرق الأصلية

لنبدأ بالتعريف بالطرق الأصلية حيث تكون هي الأكثر استخدامًا في السكربتات.

Start-Sleep

أكثر أوامر الإيقاف استخدامًا هو بلا شك، Start-Sleep. يأخذ هذا الأمر إدخالين بسيطين، هما -Seconds و -Milliseconds. يمكن أن تكون الثواني قيمة عددية من نوع System.Double بينما تأخذ الأمتار السنية قيمًا فقط من نوع System.Int32. من خلال الجمع بينهما، يمكن تحقيق التحكم الدقيق في مدى مدة التوقف. Start-Sleep لديه أيضًا اسم آخر وهو sleep.

Start-Sleep -Seconds 2 -Milliseconds 300

قبل PowerShell 6.2.0، لم يكن بإمكانك كتابة قيمة للثواني الكسرية مثل 2.3 وهو نفس الوقت الذي نقوم بالتوقف فيه في الشيفرة أعلاه. مع 6.2.0، أصبحت القيم الكسرية مدعومة الآن، لذا بدلاً من كتابة الثواني والأمتار السنية بشكل مستقل، يمكنك الآن القول: -Seconds 2.3.

من المهم أن نلاحظ أنه يمكنك الخروج من وظيفة Start-Sleep باستخدام Ctrl-C. وهذا ليس صحيحًا بالنسبة لجميع الطرق!

توقف الخيط

A less commonly used method of pausing execution is the [System.Threading.Thread]::Sleep() .NET method. By passing in a System.Int32 or a TimeSpan value, this allows pausing of the current thread for a set amount of time. For example, to pause by that same amount of time, 2.3 seconds, as in our Start-Sleep example, we can write:

[System.Threading.Thread]::Sleep(2300)

لاستخدام بناء الفترة الزمنية مع طريقة توقف الخيط، يمكنك القيام بالتالي:

[System.Threading.Thread]::Sleep([TimeSpan]::New(0, 0, 0, 2, 300))

لتوقيف الخيط بشكل لا نهائي، يمكنك استخدام [System.Threading.Timeout]::InfiniteTimeSpan ولكن عليك أن تضع في اعتبارك أن هذا قد يقفل عملية التشغيل الخاصة بك.

على عكس Start-Sleep، فإن طريقة توقف الخيط لا تتيح لك الخروج من الروتين النوم باستخدام Ctrl-C. يعتمد هذا على تطبيقك، وقد يكون هذا الأمر مرغوباً.

من الأمور المهمة أيضاً معرفتها حول توقف الخيط أنه ليس هناك ضمان تام للزمن. جميع عمليات توقف الخيط تضمن أنه سينتظر على الأقل تلك الثواني. نظرًا لأن عمليات توقف الخيط تتزامن مع علامات الساعة، فإن البرامج الأخرى قد تقاطع هذه الوظيفة التوقفية وتجبر عملية الانتظار على أن تستغرق وقتاً أطول.

بالرغم من أن توقف الخيط له استخداماته، فمن الأفضل استخدام أحد الطرق المضمنة الأخرى بسبب هذه المشاكل.

Read-Host

تصف الطرق المذكورة أعلاه طرقًا لتوقيف التنفيذ، ولكن فقط لفترة زمنية محددة. الطريقة الأخرى لتوقيف التنفيذ هي عن طريق طلب إدخال المستخدم. مع هذه الطريقة، يجب اتخاذ إجراء يدوي، لكن يمكن أن يكون من المفيد جدًا طلب تأكيد للمتابعة وربما تضمين إدخال إضافي.

Read-Host هو واحد من أكثر الطرق شيوعًا لطلب إدخال المستخدم. عن طريق طلب إدخال المستخدم، يمكن حفظ الإدخال الناتج للاستخدام في الشيفرة لاحقًا، أو لإيقاف التنفيذ حسب الضرورة.

Read-Host -Prompt "Press any key to continue"

بمجرد إدخال النص، من الضروري الضغط على مفتاح الإدخال أو العودة لمتابعة التنفيذ. من خلال القيام بذلك، ودون حفظ الإدخال في متغير، سيتم إخراج نفس النص المُدخل إلى وحدة التحكم.

Press Enter to Move Execution Along

إذا كنت ترغب في حفظ النص الناتج لاحقًا للاستخدام، ببساطة قم بتعيين إدخال Read-Host إلى متغير.

$Input = Read-Host -Prompt "Press any key to continue"

في بعض الأحيان قد ترغب في قراءة الإدخال كنص آمن. لحسن الحظ، يجعل Read-Host ذلك سهلًا للغاية.

$SecureInput = Read-Host -Prompt "Enter your password" -AsSecureString

Ctrl-C سيسمح لك بالخروج من استدعاء Read-Host.

Console ReadKey Method

باستخدام الأسلوب [Console]::ReadKey()، يمكنك بسهولة قراءة أوامر المفاتيح، مع المعدلات، أثناء توقف تنفيذ البرنامج. بشكل افتراضي، تُرسل أوامر المفاتيح المرسلة إلى الشاشة كـ كائن System.ConsoleKeyInfo. وهذا يشمل قيم الـ Key، KeyChar، وقيم الـ Modifiers، والتي يمكن أن تكون مفيدة للغاية عند التحقق من مجموعات معينة من المفاتيح.

[Console]::ReadKey()
Console ReadKey Command

غالبًا ما قد ترغب في التحقق من وجود إدخال معين قبل المتابعة بشكل مستمر. يمكن القيام بذلك بسهولة باستخدام حلقة Do-While مثلما هو موضح أدناه.

Do {
	$Key = [Console]::ReadKey($True)
	Write-Host $Key.Key
} While ( $Key.Key -NE [ConsoleKey]::Escape )
Do-While Loop Key

يرجى ملاحظة أنه نظرًا لأننا نبحث عن تركيبة مفتاح معينة، فلن يؤدي Ctrl-C إلى الخروج من الإدخال هنا.

Host RawUI ReadKey Method

وأخيرًا، لدينا الطريقة $host.UI.RawUI.ReadKey(). هذا مشابه لطريقة Console ReadKey، ولكن هذه الطريقة تسمح بتمرير خيارات إضافية إلى طريقة ReadKey للتحكم في السلوك والإخراج بشكل أفضل.

$host.UI.RawUI.ReadKey()
RawUI.ReadKey

هناك عدد من ReadKeyOptions يمكن تمريرها والتي قد تجعل طريقة RawUI ReadKey أكثر فائدة.

  • AllowCtrlC
  • IncludeKeyDown
  • IncludeKeyUp
  • NoEcho

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

$host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown')

ستسمح هذه الطريقة باستخدام Ctrl-C للخروج من الأمر، باستثناء في حال استخدام خيار AllowCtrlC.

الطرق غير الأصلية

في هذا القسم، سنستكشف بعض الطرق غير الأصلية لإيقاف تنفيذ النص البرمجي. تهدف هذه الطرق إلى استخدام برامج توافقية غير مخصصة للطرفية في PowerShell والتي يمكن دمجها في نصوص PowerShell حسب احتياجاتك.

ويندوز

Pause

الأمر الذي يوقف التنفيذ بسيط جدًا، وسيعرض اضغط على أي مفتاح للمتابعة . . . ويظل بهذه الحالة حتى يتم الضغط على مفتاح لاستئناف التنفيذ.

cmd /c 'pause'
Pause Command

قد تسأل كيفية استخدام هذا في النص، ولكن تمامًا كما تفعل مع أي أمر آخر، قم بإدراج الأمر cmd /c 'pause' داخل النص الخاص بك لاستخدام الوظيفة الأصلية.

Cmd/C Pause Command

مهلة

عادة ما يُستخدم في ملفات دفعية لنظام التشغيل Windows، يسمح أمر الـ timeout بوقف التنفيذ لعدد محدد من الثواني وتجاهل أي أوامر مفاتيح. سيستأنف تنفيذ المستخدم عادةً حتى لو لم ينقضي فترة المهلة. يُستخدم بسهولة ببساطة من خلال تمرير عدد الثواني.

# توقف لمدة 2 ثانية
timeout /t 2

# توقف لمدة 5 ثواني ولكن لا تسمح بفصل المفاتيح
timeout /t 5 /nobreak

# توقف بشكل غير محدد حتى يتم الضغط على مفتاح
timeout /t -1
Timeout Command

تمامًا كما هو الحال مع أمر pause، قم بإدراج الأمر timeout داخل النص وفي المثال أدناه، نضغط على مفتاح الإدخال للاستمرار.

Timeout Command Execution

Linux

نوم

مثل الأمر pause في نظام التشغيل Windows، يسمح أمر sleep في Linux بتحديد قيمة تعسفية للنوم. على عكس أمر الإيقاف المؤقت، يحتوي أمر sleep على بعض الخيارات الإضافية التي تسمح بمرونة في وقت النوم.

sleep 2.3s
Sleep Command

الأمر sleep لديه أيضًا اختيارياً لواحق يمكن أن تسمح بتحديد فترات زمنية أطول. أمثلة:

  • sleep 1m – النوم لمدة دقيقة واحدة
  • sleep 2h – النوم لمدة ساعتين
  • sleep 1d – النوم لمدة يوم واحد

Read -P

وأخيرًا، الطريقة الأخرى التي يمكن لنظام Linux أن يتوقف فيها هي باستخدام تطبيق read لتوقف لضغط مفتاح الإدخال لمتابعة التنفيذ. هناك معلمة اختيارية للمهلة التي ستستمر في التنفيذ إذا لم يتم ضغط مفتاح الإدخال في الوقت المحدد.

read -p 'Press enter to continue' -t 5
Read Application to Pause

الاستنتاج

كما ترون، هناك العديد من الطرق لإيقاف التنفيذ في نص أو على سطر الأوامر. اعتمادًا على احتياجاتك، يمكن أن يكون الأمر بسيطًا مثل أمر Start-Sleep أو عملية أكثر تعقيدًا تعتمد على الإدخال. بالاشتراك مع الأوامر الأساسية، يتيح التوقف في PowerShell مرونة في أي بيئة تقريبًا وأقصى فائدة للنص البرمجي.

Source:
https://adamtheautomator.com/powershell-pause/