كيف أجد المنفذ في الطرفية (الترمنال) على ماك
شغّلت npm run dev فظهرت رسالة «المنفذ 3000 قيد الاستخدام»، وتحتاج معرفة من يمسك به — من الطرفية (الترمنال). إليك ثلاثة أوامر موثوقة في طرفية ماك لربط المنفذ بالعملية على macOS، وأيّها تختار في كل موقف.
كيف أجد المنفذ في الطرفية على ماك؟
افتح الطرفية (Cmd+Space ثم اكتب «Terminal» واضغط Return) وشغّل أمراً واحداً:
lsof -nP -iTCP:3000 -sTCP:LISTEN
استبدل 3000 بالمنفذ المطلوب. عمود PID هو معرّف العملية، وعمود COMMAND هو اسم البرنامج. أداة lsof مثبّتة مسبقاً في كل إصدارات macOS — لا حاجة لـHomebrew أو npm install أو أيّ إعداد.
الإجابة المختصرة
في طرفية ماك، شغّل:
lsof -nP -iTCP:3000 -sTCP:LISTEN
استبدل 3000 بالمنفذ المطلوب. ستبدو المخرجات هكذا:
COMMAND PID USER FD TYPE DEVICE NAME
node 54231 khalouf 23u IPv6 0x... TCP *:3000 (LISTEN)
عمود PID (هنا 54231) هو إجابتك. تلك هي العملية التي تحتجز المنفذ 3000.
الإجابة الأطول (وسببها)
1. lsof — الخيار الافتراضي الصحيح
أداة lsof («اعرض الملفات المفتوحة») مثبّتة مسبقاً على macOS. ورغم اسمها، فهي تعرض كل شيء مفتوح — ملفات ومقابس وأنابيب واتصالات شبكية. والمقابس في يونكس ملفات أيضاً، لذا تظهر المنافذ المستمعة هنا.
الخيارات المهمة:
-n— لا تحوّل عناوين IP إلى أسماء (أسرع، بلا DNS).-P— لا تترجم أرقام المنافذ إلى أسماء خدمات (تريد3000لاhbci).-iTCP:3000— مطابقة TCP على المنفذ 3000. استخدم-iUDP:53لـUDP، أو-i :3000لكليهما.-sTCP:LISTEN— أَظهِر المقابس المستمعة فقط (تجاوز الاتصالات القائمة).
للسكريبتات، -t يعطيك الـPID فقط:
lsof -ti :3000 # PID مجرّد، صالح للتمرير
هذه الصياغة تظهر في السطر الشهير kill -9 $(lsof -ti :3000).
2. netstat — حين لا يتوفّر lsof
أداة netstat على macOS بنكهة BSD وتفتقر للخيار -p الذي يعرفه مستخدمو لينكس. لإظهار المقابس المستمعة:
netstat -anv -p tcp | grep LISTEN
لن ترى أسماء العمليات هنا، لكنك سترى كل المنافذ المستمعة دفعةً واحدة — مفيد حين لا تعرف بعد أيّ منفذ هو المقصود.
للانتقال من منفذ إلى PID، عُد إلى lsof. لا توجد طريقة أصيلة جيّدة لفعل ذلك بـnetstat وحدها على macOS.
3. ss — تنبيه: غير متوفّرة على macOS
إن كنت قادماً من لينكس، قد تمتدّ يدك إلى ss -ltnp. لا تفعل. ss ليست مثبّتة افتراضياً على macOS ولا تستحقّ التثبيت — lsof تكفي. (يمكنك brew install iproute2mac إن أصرّت ذاكرة العضلات، لكنه مجرّد غلاف.)
4. مسار «مراقب النشاط»
«مراقب النشاط» (Cmd+Space → "Activity Monitor") يُظهر كل العمليات الجارية مع تبويب الشبكة. مفيد لتأكيد ما يمثّله PID معيّن، لكنه لا يدعم البحث بالمنفذ. تحتاج lsof أولاً للحصول على PID، ثم «مراقب النشاط» لفحصه.
المطبّات الشائعة
مخرجات فارغة
إذا لم تُرجِع lsof -i :3000 شيئاً، ثلاثة أشياء للتحقّق:
- هل الخادم يعمل فعلاً؟ تحقّق بـ
ps aux | grep node(أو أيّ بيئة تشغيل). - هل يستمع على TCP لا UDP؟ جرّب
lsof -i :3000دون مُحدِّدTCP. - هل بُدِئ بمستخدم آخر؟ إن كان
sudo، قد تحتاجsudo lsof -i :3000لرؤيته.
عدّة PIDs
إن أعطتك lsof عدّة صفوف لمنفذ واحد، فأنت غالباً أمام أب وأطفال (مثل تجمّع Node، أو webpack-dev-server نسخ عمّالاً). أوّل PID هو ما تريده عادةً؛ الباقي يموت معه عند الإشارة.
IPv6 مقابل IPv4
macOS يفضّل IPv6. الخادم المرتبط بـ:: يظهر بنوع TYPE IPv6. lsof -iTCP:3000 يطابق كليهما، لذا نادراً ما تكون مشكلة — لكن إن كنت ترى المنفذ في المتصفّح ولا تراه في lsof، تأكّد أنك لا تُصفّي إحدى العائلتين.
بعد أن تحصل على الـPID
الخطوة التالية تعتمد على الهدف:
- تريد فقط تحرير المنفذ؟ أرسِل SIGTERM أولاً:
kill <PID>. إذا تجاهلك، صعّد:kill -9 <PID>. (لمَ ليس-9دائماً؟ راجع منشورنا حول EADDRINUSE.) - تريد معرفة ما هو؟
ps -o pid,ppid,command -p <PID>يُظهر سطر الأوامر الكامل والأب. - تريد مشاركته للعموم؟ راجع بدائل ngrok المجانية لأنفاق منافذ localhost.
أوامر جدير بحفظها
# من يحتجز المنفذ 3000؟
lsof -nP -iTCP:3000 -sTCP:LISTEN
# PID مجرّد (للسكريبتات)
lsof -ti :3000
# كل منافذ TCP المستمعة، مرتّبة
lsof -nP -iTCP -sTCP:LISTEN | tail -n +2 | sort
# أَنهِ من يحتجز المنفذ 3000 (بهدوء، ثم بالقوة)
PID=$(lsof -ti :3000) && kill $PID; sleep 2; kill -9 $PID 2>/dev/null