logo tping

محمد حاجی پور نیم‌رخ

تاریخ انتشار:

tping؛ ابزاری برای Ping با مهرزمان- بخش یکم

شاید براتون عجیب باشه که tping چیه؟! از کجا اومده؟! واقعیتش tping ساخته ذهن خودمه و چیز عجیب غریبی هم نیست، همون pingـه که تاریخ و زمان هر پاسخ رو هم نشون میده. داستان از اونجایی شروع شد که یه سوییچی تو شبکه ما ظاهرا قطع می‌شد در حد شاید 3~4 تا Request timeout و اینطور هم نبود که بطور منظم این اتفاق بیفته. شاید هر چند ساعت یه بار، بعضی مواقع چند دقیقه یه بار. خلاصه من ping -t این سوییچ رو گذاشتم و اینطور به چشم میومد که زمان زیادیه که اتفاقی نیفتاده ولی من مطمئن نبودم که Request timeoutهایی که بالاتر می‌بینم برای پیشتره یا جدیده و به همکارم گفتم «ای کاش زمان و تاریخ هر پاسخ ping کنارش بود» و این پرسش برام بوجود اومد که آیا میشه چنین خروجی‌ای از ping گرفت؟ رفتم جست‌وجو کردم دیدم ابزارهای زیادی برای ping ایجاد شده؛ fping، hping، tcping و شاید ابزارهای دیگه ولی هیچکدوم کار منو راه نمیداختن یه ping ساده و مهرزمانی کنارش. پس گفتم خودم می‌نویسمش.

گام اول؛ تلاش برای نوشتن یک Batch File

با خودم گفتم اگه بتونم به هر پاسخی که ping برمی‌گردونه یه مهرزمانی بچسبونم کار در اومده دیگه، و تو این فکر بودم که این کار رو با هدایت خروجی (output redirection) ping انجام بدم؛ یه چیزی مثل دستور زیر:

C:\>ping 8.8.8.8 > D:\Result.txt

ولی مشکل اینجاست که تو این حالت نمی‌شه چیزی بهش اضافه کرد. حالا چه کنم؟ با خودم گفتم اگه یه حلقه بی‌نهایت بنویسم که هربار فقط یکبار دستور ping رو اجرا کنه و خروجیش رو بگیرم و مهرزمان رو بهش اضافه کنم جواب رو گرفتم. خب حالا بریم تیکه تیکه جورچین‌مون رو کامل کنیم.

اول بریم یکبار دستور ping رو اجرا کنیم. می‌دونید که بطور پیشفرض دستور ping چهار بار درخواست ارسال می‌کنه ولی اگه با سوییچ n و پس از اون یه عدد به عنوان تعداد درخواست بهش بدیم به همون تعداد درخواست می‌فرسته. پس من بصورت زیر نوشتمش:

C:\>ping -n 1 8.8.8.8
Pinging 8.8.8.8 with 32 bytes of data:
Reply from 8.8.8.8: bytes=32 time=93ms TTL=112

Ping statistics for 8.8.8.8:
    Packets: Sent = 1, Received = 1, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 93ms, Maximum = 93ms, Average = 93ms

حالا از این خروجی که میده فقط قسمت اصلی جواب رو می‌خوام و باقی خطوط که آمار و اطلاعاته برام ارزشی نداره چطور اون قسمت رو جدا کنم؟ با دستور findstr، هرچند این دستور برای جست‌وجوی رشته توی فایله ولی ما می‌تونیم خروجی ping رو pipe کنیم در ادامه توضیحاتش رو می‌گم:

C:\>ping -n 1 8.8.8.8 | findstr /v /i "Ping Packets: Approx Min"
Reply from 8.8.8.8: bytes=32 time=89ms TTL=112

همونطور که گفتم دستور findstr برای جست‌وجوی رشته در یک فایله ولی خب ما اینجا بجای فایل خروجی دستور ping رو بهش pipe کردیم و روی اون جست‌وجو رو انجام میده.

  • سوییچ v/ میگه خط‌هایی رو برام بیار که شامل این عبارات “Ping Packets: Approx Min” نباشه که میشه خط دوم خروجی دستور ping -n 1.
  • سوییچ i/ میگه به بزرگی یا کوچکی حروف حساس نباش.

خب حالا باید تاریخ و ساعت رو بچسبونم قبلش اما چطور؟ پیش از اینکه ادامه بدم باید بگم چون اسکریپتمون قراره طولانی باشه از اینجا به بعد رو پیشنهاد می‌کنم تو یه notepad بنویسید و با پسوند bat ذخیره کنید من اسم فایلم رو می‌ذارم tping.bat و تو ریشه درایو C میذارمش، سپس داخل فایلم چنین چیزی می‌نویسم:

for /f "tokens=*" %%a ^
in ('ping -n 1 8.8.8.8 ^|findstr /v "Ping Packets: Approx Min"') ^
do (call echo [%%date%% %%time%%] %%a)

و حالا اجراش می‌کنم:

C:\>tping.bat
[30/06/2025 23:04:47.90] Reply from 8.8.8.8: bytes=32 time=70ms TTL=112

هوراااااا 🙂 این دقیقا همون چیزیه که می‌خواستم. خب حالا این دستور چی کار کرد؟

  • for برای ایجاد حلقه است. و این مدل for از قوی‌ترین کارهایی که میشه با for کرد.
  • سوییچ f/ به for ما می‌فهمونه که باید روی خروجی یک دستور یا خطوط یک فایل کار کنه.
  • “*=tokens” میگه که هر خطی که اومد همه رو بگیر و بریز تو متغیر.
  • a%% متغیر ماست و هر خط رو برامون نگه‌می‌داره.
  • ^ به کنسول میگه که دستور هنوز تموم نشده و ادامش خط بعدی اومده.
  • بعد از in ما ورودی رو به for مون میدیم که میتونه یه دستور، یه رشته یا فایل باشه که ما دستور دادیم بهش.
  • do هم کاری که باید انجام بشه رو مشخص می‌کنه که برای ما چاپ کردن مهرزمان قبل از رشته داخل متغیرمونه.
  • دستور call یه batch رو اجرا می‌کنه اگه call رو ننویسیم مقادیر متغیرهای تاریخ و ساعت چاپ نمیشن که دلیلش مربوط میشه به شیوه پردازش متغیرها توی حلقه for.

خب یه مرحله دیگه مونده. باید این دستور رو بندازیم تو یه for بی‌نهایت تا بطور خودکار اجرا شه. من اینجا ساختار for بی‌نهایت رو میگم بعد دستور قبلی رو میندازم توش و در کل کارمون تمومه.

C:\> for /l %%i in () do echo Hi
C:\>echo hi
hi
C:\>echo hi
hi
C:\>echo hi
hi

سوییچ l/ به for می‌فهمونه که باید از یه نقطه آغاز با یه گام ثابت به یه نقطه پایان برسه. این نقاط آغاز و پایان و گام تو پرانتز بعد in نوشته میشن ولی از اونجایی که من میخوام حلقه بی‌نهایت باشه هیچکدوم رو ننوشتم. حالا دستور قبلی رو میذارم تو دل این دستور:

for /l %%i in ()^
do (for /f "tokens=*" %%a ^
in ('ping -n 1 8.8.8.8 ^|findstr /v "Ping Packets: Approx Min"') ^
do (call echo [%%date%% %%time%%] %%a))

خب کار ما تقریبا تموم شد فقط یه مورد دیگه هم داره که اگه اسکریپت رو اجرا کرده باشین متوجهش شدید؛ خیلی سریع اجرا میشه من میخوام مثلا هر یه ثانیه یه بار اجرا بشه برای این کار باید دستوری بنویسیم که بعد از چاپ خروجی یه ثانیه تاخیر ایجاد کنه؛ دستور timeout برای این موقعست:

for /l %%i in ()^
do (for /f "tokens=*" %%a ^
in ('ping -n 1 8.8.8.8 ^|findstr /v "Ping Packets: Approx Min"') ^
do (call echo [%%date%% %%time%%] %%a)
timeout /nobreak /t 1 >nul)
  • سوییچ nobreak/ میگه که هر کلیدی زده شد نادیده بگیر تا زمان سپری شه.
  • t/ عددی از 1- تا 99999 برحسب ثانیه میگیره و به همون مقدار صبر می‌کنه.
  • از اونجایی که این دستور یه خروجی داره که زمان باقیمانده رو میگه null< باعث میشه که خروجی رو نشون نده.

خب در نهایت خروجی اسکریپت ما شبیه چیزی میشه که پایین اومده:

C:\>tping.bat 
[01/07/2025 21:15:42.74] Reply from 8.8.8.8: bytes=32 time=95ms TTL=111
[01/07/2025 21:15:43.33] Reply from 8.8.8.8: bytes=32 time=61ms TTL=111
[01/07/2025 21:15:44.27] Reply from 8.8.8.8: bytes=32 time=61ms TTL=111
[01/07/2025 21:15:45.33] Reply from 8.8.8.8: bytes=32 time=67ms TTL=111
[01/07/2025 21:15:46.30] Reply from 8.8.8.8: bytes=32 time=68ms TTL=111
[01/07/2025 21:15:47.35] Reply from 8.8.8.8: bytes=32 time=68ms TTL=111
[01/07/2025 21:15:48.30] Reply from 8.8.8.8: bytes=32 time=68ms TTL=111
[01/07/2025 21:15:49.25] Reply from 8.8.8.8: bytes=32 time=63ms TTL=111
[01/07/2025 21:15:50.30] Reply from 8.8.8.8: bytes=32 time=63ms TTL=111
Terminate batch job (Y/N)? y

برای توقفش از کلیدهای Ctrl+C یا Ctrl+Pause/Break استفاده می‌کنیم و در پاسخ Y رو میزنیم. و تمام.

💡 نکته

شاید به نظر بیاد که این ابزار خیلی کاربردی نیست، ابزارهای پایش (Monitoring) شبکه برای همین کاره دیگه؛ درسته ولی خیلی وقت‌ها یه ابزار سَبُک و دم دستی از خیلی از ابزارهای حرفه‌ای کار راه‌بندازتره و همچنین برای خودم انگیزه‌ای شد دانشم در مورد دستورهای CMD و Batch Fileها بیشتر بشه.

امیدوارم که این نوشته‌ هم یه جایی به کارتون بیاد. خوشحال میشم اگه نکته‌ای داشتین در قسمت دیدگاه‌ها برام بنویسید.

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *