8 lệnh để quản lý hiệu quả các tiến trình trong Linux

Nói chung, có 3 trạng thái chính trong vòng đời của một tiến trình ứng dụng: Bắt đầu, chạy và dừng. Nếu muốn trở thành quản trị viên có năng lực, bạn cần biết cách quản lý mỗi trạng thái một cách cẩn thận. 8 lệnh sau đây có thể được sử dụng để giúp bạn quản lý toàn bộ vòng đời của tiến trình.

Nếu muốn trở thành quản trị viên có năng lực, bạn cần biết cách quản lý trạng thái của các tiến trình
Nếu muốn trở thành quản trị viên có năng lực, bạn cần biết cách quản lý trạng thái của các tiến trình

Bắt đầu tiến trình

Cách dễ nhất để bắt đầu một tiến trình là nhập tên của nó trên dòng lệnh, sau đó nhấn Enter. Nếu muốn khởi động nginx web server, hãy nhập nginx. Có lẽ bạn sẽ muốn xem phiên bản của nó.

alan@workstation:~ $nginx
alan@workstation:~ $nginx -v
nginx version:nginx/1.14.0

Xem đường dẫn thực thi

Bản demo của tiến trình khởi động ở trên giả định rằng file thực thi nằm trong đường dẫn thực thi của bạn. Hiểu đường dẫn này là chìa khóa để bắt đầu và quản lý các tiến trình một cách đáng tin cậy. Các quản trị viên thường tùy chỉnh đường dẫn này theo mục đích họ muốn. Bạn có thể sử dụng echo $path để xem đường dẫn thực thi

alan@workstation:~ $echo $path
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin

which

Sử dụng lệnh which để xem đường dẫn đầy đủ của file thực thi.

alan@workstation:~ $which nginx
/opt/nginx/bin/nginx

Bài viết sẽ sử dụng phần mềm web server phổ biến nginx làm ví dụ. Giả sử nginx đã được cài đặt. Nếu bạn thực thi lệnh which nginx và không có gì được trả về, thì nghĩa là không thể tìm thấy nginx, vì lệnh chỉ tìm kiếm đường dẫn thực thi mà bạn đã chỉ định. Có 3 cách để khắc phục tình huống không thể bắt đầu một tiến trình bằng tên. Đầu tiên là nhập đường dẫn đầy đủ:

alan@workstation:~ $/home/alan/web/prod/nginx/sbin/nginx -v
nginx version:nginx/1.14.0

Giải pháp thứ hai là cài đặt ứng dụng trong một thư mục thuộc đường dẫn thực thi, tuy nhiên, điều này đôi khi có thể không thực hiện được, đặc biệt nếu bạn không có quyền root.

Giải pháp thứ ba là cập nhật biến môi trường đường dẫn thực thi của bạn, bao gồm thư mục cài đặt cho ứng dụng cụ thể mà bạn muốn sử dụng. Giải pháp này liên quan đến shell. Ví dụ, người dùng bash cần chỉnh sửa dòng path= trong file .bashrc.

path="$home/web/prod/nginx/sbin:$path"

Bây giờ, lặp lại lệnh echo và which hoặc thử kiểm tra phiên bản.

alan@workstation:~ $echo $path
/home/alan/web/prod/nginx/sbin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
alan@workstation:~ $which nginx
/home/alan/web/prod/nginx/sbin/nginx
alan@workstation:~ $nginx -v
nginx version:nginx/1.14.0

Tiếp tục chạy tiến trình

nohup

Khi bạn đăng xuất hoặc đóng Terminal, tiến trình có thể không tiếp tục. Trong trường hợp đặc biệt này, bạn có thể giữ cho tiến trình chạy bằng cách đặt lệnh nohup trước lệnh muốn chạy. Ngoài ra, thêm một dấu ở cuối và tiến trình sẽ được chạy ở chế độ nền, cho phép bạn tiếp tục sử dụng Terminal. Ví dụ bạn muốn chạy myprogram.sh.

nohup myprogram.sh&

nohup trả về pid của tiến trình đang chạy.

Quản lý các tiến trình đang chạy

Mỗi tiến trình có một số nhận dạng duy nhất (pid). Con số này là những gì người dùng sử dụng để quản lý từng tiến trình (bạn cũng có thể sử dụng tên tiến trình). Có một số lệnh để kiểm tra trạng thái của một tiến trình đang chạy. Hãy xem nhanh các lệnh này.

ps

Phổ biến nhất là lệnh ps. Đầu ra mặc định của ps là một danh sách đơn giản các tiến trình đang chạy trong Terminal hiện tại, như sau, cột đầu tiên chứa pid.

alan@workstation:~ $ps
pid tty time cmd
23989 pts/0 00:00:00 bash
24148 pts/0 00:00:00 ps

Ví dụ, bạn muốn xem tiến trình nginx đã bắt đầu trước đó. Để làm điều này, bạn cần yêu cầu ps chỉ cho mình mọi tiến trình đang chạy (-e) và danh sách đầy đủ (-f).

alan@workstation:~ $ps -ef
uid pid ppid c stime tty time cmd
root 1 0 0 aug18?00:00:10/sbin/init splash
root 2 0 0 aug18?00:00:00 [kthreadd]
root 4 2 0 aug18?00:00:00 [kworker/0:0h]
root 6 2 0 aug18?00:00:00 [mm_percpu_wq]
root 7 2 0 aug18?00:00:00 [ksoftirqd/0]
root 8 2 0 aug18?00:00:20 [rcu_sched]
root 9 2 0 aug18?00:00:00 [rcu_bh]
root 10 2 0 aug18?00:00:00 [migration/0]
root 11 2 0 aug18?00:00:00 [watchdog/0]
root 12 2 0 aug18?00:00:00 [cpuhp/0]
root 13 2 0 aug18?00:00:00 [cpuhp/1]
root 14 2 0 aug18?00:00:00 [watchdog/1]
root 15 2 0 aug18?00:00:00 [migration/1]
root 16 2 0 aug18?00:00:00 [ksoftirqd/1]
alan 20506 20496 0 10:39 pts/0 00:00:00 bash
alan 20520 1454 0 10:39?00:00:00 nginx:master process nginx
alan 20521 20520 0 10:39?00:00:00 nginx:worker process
alan 20526 20506 0 10:39 pts/0 00:00:00 man ps
alan 20536 20526 0 10:39 pts/0 00:00:00 pager
alan 20564 20496 0 10:40 pts/1 00:00:00 bash

Bạn có thể thấy tiến trình nginx trong đầu ra của lệnh ps ở trên. Lệnh này hiển thị gần 300 dòng, nhưng đã được rút ngắn nó trong ví dụ này. Như bạn có thể tưởng tượng, việc cố gắng xử lý 300 dòng thông tin tiến trình sẽ hơi khó khăn. Bạn có thể chuyển đầu ra này thành grep và lọc nó để chỉ hiển thị nginx.

alan@workstation:~ $ps -efgrep nginx
alan 20520 1454 0 10:39?00:00:00 nginx:master process nginx
alan 20521 20520 0 10:39?00:00:00 nginx:worker process

Bạn có thể nhanh chóng thấy rằng pid của nginx là 2052020521.

pgrep

Lệnh pgrep đơn giản hóa các vấn đề gặp phải khi gọi chỉ mình grep.

alan@workstation:~ $pgrep nginx
20520
20521

Giả sử bạn đang ở trong một môi trường được host, nhiều người dùng đang chạy một số phiên bản nginx khác nhau. Bạn có thể sử dụng tùy chọn -u để loại trừ những người khác khỏi đầu ra.

alan@workstation:~ $pgrep -u alan nginx
20520
20521

pidof

Một lệnh hữu ích khác là pidof. Lệnh này sẽ kiểm tra pid của một file nhị phân cụ thể, ngay cả khi một tiến trình khác có cùng tên đang chạy. Để xây dựng một ví dụ, tác giả bài viết đã sao chép nginx của mình vào thư mục thứ hai và bắt đầu với tiền tố đường dẫn tương ứng. Trong thực tế, ví dụ này có thể ở một vị trí khác, chẳng hạn các thư mục thuộc sở hữu của những người dùng khác nhau. Nếu chạy hai phiên bản nginx, đầu ra pidof hiển thị tất cả các tiến trình.

alan@workstation:~ $ps -efgrep nginx
alan 20881 1454 0 11:18?00:00:00 nginx:master process ./nginx -p/home/alan/web/prod/nginxsec
alan 20882 20881 0 11:18?00:00:00 nginx:worker process
alan 20895 1454 0 11:19?00:00:00 nginx:master process nginx
alan 20896 20895 0 11:19?00:00:00 nginx:worker process

Sử dụng grep hoặc pgrep sẽ hiển thị số pid, nhưng bạn có thể không biết đó là phiên bản nào.

alan@workstation:~ $pgrep nginx
20881
20882
20895
20896

Lệnh pidof có thể được sử dụng để xác định pid của từng phiên bản nginx cụ thể.

alan@workstation:~ $pidof/home/alan/web/prod/nginxsec/sbin/nginx
20882 20881
alan@workstation:~ $pidof/home/alan/web/prod/nginx/sbin/nginx
20896 20895

top

Lệnh top có lịch sử lâu đời, rất hữu ích để xem chi tiết các tiến trình đang chạy và nhanh chóng xác định những vấn đề như tiêu thụ bộ nhớ. Chế độ xem mặc định của nó được hiển thị bên dưới.

top-11:56:28 up 1 day, 13:37, 1 user, load average:0.09, 0.04, 0.03
tasks:292 total, 3 running, 225 sleeping, 0 stopped, 0 zombie
%cpu (s):0.1 us, 0.2 sy, 0.0 ni, 99.7 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
kib mem:16387132 total, 10854648 free, 1859036 used, 3673448 buff/cache
kib swap:0 total, 0 free, 0 used. 14176540 avail mem
 pid user pr ni virt res shr s%cpu%mem time + command
17270 alan 20 0 3930764 247288 98992 r 0.7 1.5 5:58.22 gnome-shell
20496 alan 20 0 816144 45416 29844 s 0.5 0.3 0:22.16 gnome-terminal-
21110 alan 20 0 41940 3988 3188 r 0.1 0.0 0:00.17 top
 1 root 20 0 225564 9416 6768 s 0.0 0.1 0:10.72 systemd
 2 root 20 0 0 0 0 s 0.0 0.0 0:00.01 kthreadd
 4 root 0 -20 0 0 0 i 0.0 0.0 0:00.00 kworker/0:0h
 6 root 0 -20 0 0 0 i 0.0 0.0 0:00.00 mm_percpu_wq
 7 root 20 0 0 0 0 s 0.0 0.0 0:00.08 ksoftirqd/0

Bạn có thể thay đổi khoảng thời gian cập nhật bằng cách nhập ký tự s và số giây cập nhật ưa thích. Để dễ dàng theo dõi tiến trình nginx mẫu, ví dụ có thể sử dụng tùy chọn -p và chuyển pid để gọi top. Đầu ra này gọn gàng hơn nhiều.

alan@workstation:~ $top -p20881 -p20882 -p20895 -p20896
tasks:4 total, 0 running, 4 sleeping, 0 stopped, 0 zombie
%cpu (s):2.8 us, 1.3 sy, 0.0 ni, 95.9 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
kib mem:16387132 total, 10856008 free, 1857648 used, 3673476 buff/cache
kib swap:0 total, 0 free, 0 used. 14177928 avail mem
pid user pr ni virt res shr s%cpu%mem time + command
20881 alan 20 0 12016 348 0 s 0.0 0.0 0:00.00 nginx
20882 alan 20 0 12460 1644 932 s 0.0 0.0 0:00.00 nginx
20895 alan 20 0 12016 352 0 s 0.0 0.0 0:00.00 nginx
20896 alan 20 0 12460 1628 912 s 0.0 0.0 0:00.00 nginx

Trong quá trình quản lý, đặc biệt là khi kết thúc một tiến trình, điều quan trọng là phải xác định chính xác pid. Ngoài ra, nếu top được sử dụng theo cách này, bất cứ khi nào một trong các tiến trình này dừng lại hoặc một tiến trình mới bắt đầu, top cần được thông báo về những tiến trình mới.

Kết thúc tiến trình

kill

Điều thú vị là không có lệnh stop. Trong Linux, chỉ có lệnh kill. Lệnh kill được sử dụng để gửi một tín hiệu đến một tiến trình. Các tín hiệu phổ biến nhất là "sigterm" hoặc "sigkill". Tuy nhiên, còn nhiều hơn thế. Sau đây là một số ví dụ, danh sách đầy đủ có thể được hiển thị với kill -l.

1) sighup 2) sigint 3) sigquit 4) sigill 5) sigtrap
6) sigabrt 7) sigbus 8) sigfpe 9) sigkill 10) sigusr1
11) sigsegv 12) sigusr2 13) sigpipe 14) sigalrm 15) sigterm

Lưu ý tín hiệu thứ 9 là sigkill. Thông thường, bạn sẽ gửi một lệnh gì đó giống như lệnh kill -9 20896. Tín hiệu mặc định là 15 - sigterm. Hãy nhớ rằng nhiều ứng dụng có các phương pháp dừng riêng của chúng. Nginx sử dụng tùy chọn -s để chuyển tín hiệu, chẳng hạn như dừng hoặc load lại. Nói chung, đa phần mọi người thích sử dụng phương pháp dành riêng cho ứng dụng để dừng hoạt động, tuy nhiên, bài viết sẽ chứng minh bằng cách sử dụng lệnh kill để dừng quy trình nginx 20896, sau đó sử dụng pgrep để xác nhận rằng nó đã dừng. Pid 20896 không còn xuất hiện nữa.

alan@workstation:~ $kill -9 20896
alan@workstation:~ $pgrep nginx
20881
20882
20895
22123

pkill

Lệnh pkill tương tự như pgrep ở chỗ nó có thể tìm kiếm theo tên, điều này có nghĩa là bạn phải rất cẩn thận khi sử dụng pkill. Trong ví dụ nginx này, nếu chỉ muốn dừng 1 phiên bản nginx, có lẽ bạn sẽ không chọn sử dụng pkill. Bạn có thể chuyển tùy chọn nginx -s stop cho một phiên bản cụ thể để loại bỏ nó, hoặc sử dụng grep để lọc toàn bộ đầu ra ps.

/home/alan/web/prod/nginx/sbin/nginx -s stop
/home/alan/web/prod/nginxsec/sbin/nginx -s stop

Nếu muốn sử dụng pkill, bạn có thể bao gồm tùy chọn -f để cho phép pkill lọc toàn bộ đối số dòng lệnh. Điều này tất nhiên cũng áp dụng cho pgrep. Vì vậy, khi thực thi pkill -f, trước hết, bạn có thể sử dụng pgrep -a. Xác nhận nó.

alan@workstation:~ $pgrep -a nginx
20881 nginx:master process ./nginx -p/home/alan/web/prod/nginxsec
20882 nginx:worker process
20895 nginx:master process nginx
20896 nginx:worker process

Bạn cũng có thể sử dụng pgrep -f để thu hẹp kết quả của mình. pkill dừng tiến trình với các thông số tương tự.

alan@workstation:~ $pgrep -f nginxsec
20881
alan@workstation:~ $pkill -f nginxsec

Điều quan trọng cần nhớ về pgrep (đặc biệt là pkill) là bạn phải luôn đảm bảo rằng kết quả tìm kiếm của mình là chính xác, Bằng cách này bạn sẽ không vô tình làm ảnh hưởng đến quá trình không chính xác.

Hầu hết các lệnh này có nhiều tùy chọn, vì vậy, bạn nên đọc trang man cho mỗi lệnh. Mặc dù hầu hết các lệnh này tồn tại trên những nền tảng như linux, solaris và bsd, nhưng vẫn có một số khác biệt. Khi làm việc trên dòng lệnh hoặc viết script, hãy luôn kiểm tra và sẵn sàng sửa chữa khi cần thiết.

Xem thêm:

Thứ Sáu, 27/11/2020 08:10
51 👨 3.013
0 Bình luận
Sắp xếp theo
    ❖ Linux