Dừng chương trình node.js từ dòng lệnh


304

Tôi có một máy chủ TCP đơn giản lắng nghe trên một cổng.

var net = require("net");

var server = net.createServer(function(socket) {
    socket.end("Hello!\n");
});

server.listen(7777);

Tôi khởi động nó node server.jsvà sau đó đóng nó bằng Ctrl + Z trên máy Mac. Khi tôi cố chạy lại nó, node server.jstôi nhận được thông báo lỗi này:

node.js:201
        throw e; // process.nextTick error, or 'error' event on first tick
          ^
Error: listen EADDRINUSE
at errnoException (net.js:670:11)
at Array.0 (net.js:771:26)
at EventEmitter._tickCallback (node.js:192:41)

Tôi đóng chương trình sai cách? Làm thế nào tôi có thể ngăn chặn điều này xảy ra?


2
Có lẽ đáng để thêm rằng Ctrl-Z tạm dừng một lệnh trên * NIX và không đóng nó. Nếu bạn nhập fgsau Ctrl-Z, bạn sẽ quay lại nơi bạn rời đi. Vì vậy, nút trước đó của bạn vẫn đang chạy. Xem ra nếu bạn đang làm điều này cho các lệnh khác quá!
ruffin

1
@ruffin đây nên là một câu trả lời. Nếu bạn đã thực hiện Ctrl+Zhành động, một phương pháp thích hợp có thể là fglàm sống lại quá trình, và sau đó Ctrl+Cgiết nó đúng cách.
Nhà siêu âm

Câu trả lời:


393

Để kết thúc chương trình, bạn nên sử dụng Ctrl+ C. Nếu bạn làm điều đó, nó sẽ gửi SIGINT, cho phép chương trình kết thúc một cách duyên dáng, không bị ràng buộc từ bất kỳ cổng nào mà nó đang nghe.

Xem thêm: https://superuser.com/a/262948/48624


21
Ctrl + Ckhông làm việc cho tôi. Chỉ ^Cđược gõ vào bảng điều khiển và chương trình không thoát.
Eleeist

1
@Eleeist, Bạn đang sử dụng thiết bị đầu cuối là gì? Đó là công việc tốt cho tôi.
Brad

2
@Eleeist, Bạn có thể đã ánh xạ lại chìa khóa của bạn hoặc một cái gì đó. Ctrl+Choạt động tốt Trong mọi trường hợp, đó là một vấn đề riêng biệt với vấn đề thực sự của bạn. Bạn nên đăng câu hỏi "Ctrl + C không hoạt động" tại SuperUser.com.
Brad

1
@ jt0dd Bạn luôn có thể kill -9, nhưng tôi thì không. Bạn có thực sự chắc chắn rằng ứng dụng của bạn vẫn là cổng duy nhất mở không? Tôi chưa bao giờ gặp vấn đề đó. Ngay khi ứng dụng của tôi kết thúc, các kết nối luôn bị chấm dứt ngay lập tức. Tôi sẽ sử dụng netstat để xác định xem ứng dụng của bạn hoặc thứ gì khác đang tồn tại trên cổng đó.
Brad

1
Tôi đã đối mặt với vấn đề này khi tôi đang sử dụng loại bàn phím trên ngôn ngữ khác. Hãy chắc chắn rằng ngôn ngữ nhập mac của bạn là tiếng Anh
Fa.Shapouri

325

Ctrl+ Zđình chỉ nó, có nghĩa là nó vẫn có thể chạy.

Ctrl+ Csẽ thực sự giết nó.

bạn cũng có thể giết nó bằng tay như thế này:

ps aux | grep node

Tìm ID tiến trình (thứ hai từ bên trái):

kill -9 PROCESS_ID

Điều này cũng có thể làm việc

killall node

ctrl + c sẽ hoạt động nhưng không có lệnh nào trong số này hoạt động với tôi. Tôi không biết tại sao? Và tôi đang tìm giải pháp dòng lệnh
kiwi tức giận

7
Hãy cẩn thận với nút killall, bạn có thể giết quá trình mà bạn không muốn giết nếu chúng khớp với "nút"
Samuel Bolduc

1
bạn có thể muốn đi lên killall nodetrong câu trả lời của mình vì đó thực sự là lựa chọn dễ dàng và đáng tin cậy nhất (miễn là bạn ổn với việc giết tất cả các trường hợp)
Boern

4
'Killall' không được công nhận là lệnh nội bộ hoặc bên ngoài, chương trình có thể hoạt động hoặc tệp bó. Tui bỏ lỡ điều gì vậy?
Ayyash

Tương tự ở đây ... Không có câu trả lời? Nó nói 'killall' không được công nhận. Không có lệnh nào khác làm việc cả. Tôi có cần phải khởi động lại máy tính của tôi hay không?
phương pháp

37

Hoặc cách khác, bạn có thể thực hiện tất cả những điều này trong một dòng:

kill -9 $(ps aux | grep '\snode\s' | awk '{print $2}')

Bạn có thể thay thế nút bên trong '\ snode \ s' bằng bất kỳ tên quy trình nào khác.


2
luân phiên, bạn luôn có thể thử: ps -ef | "nút" grep | awk '{in $ 2}' | xargs kill -9
frymaster 16/07/2015

Có vẻ như để làm việc nhưng không đúng cách đưa tôi trở lại một dấu nhắc. Suy nghĩ?
Devil's Advocate

25

Tiếp tục và tiêu diệt quá trình:

Ctrl+ Zđình chỉ nó, có nghĩa là nó vẫn đang chạy như một quá trình nền bị đình chỉ.

Bây giờ bạn có thể tại một dấu nhắc thiết bị đầu cuối ...

  1. Đưa ra lệnh fgđể tiếp tục quá trình ở phía trước.

  2. Ctrl+ Cđể giết nó đúng cách.


Ngoài ra, bạn có thể giết nó bằng tay như thế này:

( LƯU Ý: các lệnh sau có thể yêu cầu root, sudo ...bạn của bạn cũng vậy)

pkill -9 node

hoặc, nếu bạn không có pkill, điều này có thể hoạt động:

killall node

hoặc có lẽ thế này:

kill $(ps -e | grep node | awk '{print $1}')

đôi khi quá trình sẽ liệt kê grep của chính nó, trong trường hợp đó bạn sẽ cần:

kill $(ps -e | grep dmn | awk '{print $2}')

.


h / t @ruffin từ các bình luận về chính câu hỏi. Tôi đã có cùng một vấn đề và nhận xét của anh ấy đã giúp tôi tự giải quyết nó.


22

bạn có thể gõ .exit để thoát nút js REPL


2
Điều đó giả định rằng bạn đang ở REPL để bắt đầu. Nếu tôi có một tập lệnh Node đang chạy thì sao?
IgorGanapolsky

18

Nếu bạn đang chạy Node.js tương tác (REPL):

Ctrl+ Csẽ đưa bạn trở lại> dấu nhắc rồi gõ:

process.exit()

hoặc chỉ sử dụng Ctrl+ D.


17

$ sudo killall nodetrong một thiết bị đầu cuối khác hoạt động trên mac , trong khi killall nodekhông hoạt động:

$ killall node
No matching processes belonging to you were found

13

trên linux hãy thử: pkill node

trên cửa sổ:

Taskkill /IM node.exe /F

hoặc là

from subprocess import call

call(['taskkill', '/IM', 'node.exe', '/F'])

5

Mặc dù đây là một câu trả lời muộn, tôi đã tìm thấy điều này từ các tài liệu của NodeJS :

Sự kiện 'exit' được phát ra khi REPL được thoát bằng cách nhận .exitlệnh làm đầu vào, người dùng nhấn <ctrl>-Chai lần để báo hiệu SIGINT hoặc bằng cách nhấn <ctrl>-Dđể báo hiệu 'end' trên luồng đầu vào. Cuộc gọi lại người nghe được gọi mà không có bất kỳ đối số.

Vì vậy, để tóm tắt, bạn có thể thoát bằng cách:

  1. .exitvào nút REPL.
  2. Nhấn <ctrl>-Chai lần.
  3. bức xúc <ctrl>-D.
  4. process.exit(0)có nghĩa là một lối thoát tự nhiên từ REPL. Nếu bạn muốn trả về bất kỳ trạng thái nào khác, bạn có thể trả về một số khác không.
  5. process.kill(process.pid) là cách để giết bằng cách sử dụng api của nodejs từ trong mã của bạn hoặc từ REPL.

5

Tôi đang thêm câu trả lời này bởi vì đối với nhiều dự án có triển khai sản xuất, chúng tôi có các kịch bản dừng các quy trình này để chúng tôi không phải thực hiện.

Một cách rõ ràng để quản lý các quy trình Máy chủ Node của bạn là sử dụng forevergói (từ NPM).

Thí dụ:

Cài đặt mãi mãi

npm install forever -g

Chạy máy chủ nút

forever start -al ./logs/forever.log -ao ./logs/out.log -ae ./logs/err.log server.js

Kết quả:

info: Forever processing file: server.js

Tắt máy chủ nút

forever stop server.js

Kết quả

info: Forever stopped process: uid command script forever pid id logfile uptime [0] sBSj "/usr/bin/nodejs/node" ~/path/to/your/project/server.js 23084 13176 ~/.forever/forever.log 0:0:0:0.247

Điều này sẽ tắt sạch ứng dụng Máy chủ của bạn.


3

Nếu bạn muốn dừng máy chủ của bạn với npm stophoặc một cái gì đó như thế này. Bạn có thể viết mã giết quá trình máy chủ của bạn dưới dạng:

require('child_process').exec(`kill -9 ${pid}`)

Kiểm tra liên kết này để biết chi tiết: https://gist.github.com/dominhhai/aa7f3314ad27e2c50fd5


2

Tôi gặp phải một vấn đề trong đó tôi có nhiều máy chủ nút đang chạy và tôi muốn giết một trong số chúng và triển khai lại nó từ một tập lệnh.

Lưu ý: Ví dụ này nằm trong bash shell trên Mac.

Để làm như vậy tôi đảm bảo thực hiện nodecuộc gọi của mình càng cụ thể càng tốt. Ví dụ, thay vì gọi node server.jstừ thư mục ứng dụng, tôi gọinode app_name_1/app/server.js

Sau đó tôi có thể giết nó bằng cách sử dụng:

kill -9 $(ps aux | grep 'node\ app_name_1/app/server.js' | awk '{print $2}')

Điều này sẽ chỉ giết quá trình nút chạy app_name_1 / app / server.js.

Nếu bạn chạy node app_name_2/app/server.jsquá trình nút này sẽ tiếp tục chạy.

Nếu bạn quyết định bạn muốn giết chúng, tất cả những gì bạn có thể sử dụng killall nodenhư những người khác đã đề cập.


2

Trả lời muộn nhưng trên windows, mở trình quản lý tác vụ bằng CTRL + ALT + DEL sau đó giết các quy trình Node.js sẽ giải quyết lỗi này.


2

bạn có thể làm việc theo lệnh để được cụ thể trong tiêu diệt máy chủ cục bộ (ở đây: 8000)

http: // localhost: 8000 / giết PID (processId):

$:lsof -i tcp:8000

Nó sẽ cung cấp cho bạn các nhóm TCP sau:

NGƯỜI DÙNG ĐIỀU KHIỂN NGƯỜI DÙNG FD LOẠI THIẾT BỊ THIẾT BỊ / TẮT NODE

nút 21521 ubfox 12u IPv6 345668 0t0 TCP *: 8000 (LISTEN)

$:kill -9 21521

Nó sẽ giết processId tương ứng với TCP *: 8000


2

Dành cho MacOS

  1. Thiết bị đầu cuối mở
  2. Chạy mã dưới đây và nhấn enter

     sudo kill $(sudo lsof -t -i:4200)

2

Bạn có thể sử dụng bộ nhiệt áp để có được những gì bạn muốn được thực hiện.

Để có được id quá trình của các tác vụ đang chạy trên một cổng, bạn có thể thực hiện:

fuser <<target_port>>/tcp

Giả sử cổng là 8888, lệnh trở thành:

fuser 8888/tcp

Và để giết một tiến trình đang chạy trên một cổng, chỉ cần thêm công tắc -k.

fuser <<target_port>>/tcp -k

Ví dụ (cổng là 8888):

fuser 8888/tcp -k

Đó là nó! Nó sẽ đóng quá trình nghe trên cổng. Tôi thường làm điều này trước khi chạy ứng dụng máy chủ của tôi.


1

Trường hợp sử dụng của tôi: trên MacOS , chạy / chạy lại nhiều máy chủ nút trên các cổng khác nhau từ một tập lệnh

chạy :"cd $PATH1 && node server1.js & cd $PATH2 && node server2.js & ..."

dừng 1 :"kill -9 $(lsof -nP -i4TCP:$PORT1 | grep LISTEN | awk '{print $2}')"

dừng 2, dừng 3 ...

chạy lại :"stop1 & stop2 & ... & stopN ; run

để biết thêm thông tin về cách tìm quy trình theo cổng: Ai đang nghe trên một cổng TCP nhất định trên Mac OS X?


0

Đối với các cửa sổ trước tiên hãy tìm kiếm PID với số cổng của bạn

netstat -ano | findStr "portNumber"

Sau đó, giết tác vụ, đảm bảo bạn đang ở trong ổ đĩa "c" của bạn nhập mô tả hình ảnh ở đây Và lệnh sẽ làtaskkill /F /PID your pid


0

nếu bạn đang sử dụng VS Code và thiết bị đầu cuối chọn nút từ danh sách thả xuống bên phải trước rồi thực hiện Ctrl + C. Sau đó, nó sẽ hoạt động

nhập mô tả hình ảnh ở đây

Nhấn y khi bạn được nhắc.

nhập mô tả hình ảnh ở đây

Cảm ơn

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.