shell `trap` là gì (for shell beginner)
Bash
10
White

Hoàng Minh Trung viết ngày 14/03/2016

Theo định nghĩa mình tìm được ở đây thì lệnh trap trong shell script có nghĩa là

The trap command allows you to execute a command when a signal is received by your script. It works like this:

Chỉ nhìn qua định nghĩa thì khá khó hiểu nên mình viết tổng hợp lại cho các bạn nào còn mù mờ giống mình.

Signal là gì

Khi một process đang chạy thì nó có thể gửi cũng như nhận được các tín hiệu, hay còn gọi là signal. Hay được sử dụng nhất chính là tín hiệu để thịt một process như là SIGINT hay là SIGKILL. Để gửi tín hiệu này thì chắc các bạn đã biết đến tiện ích kill của linux, hay là sử dụng short cut Ctrl + C.

kill -9 [Pid]

Option -9 ở đây có nghĩa là gửi SIGKILL đến process có id là Pid.
Signal này "khoẻ" đến mức là dù process có đang ở trạng thái thế nào đi nữa thì cũng sẽ bị kill ngay tức khắc.
Ngoài option -9 này thì chúng ta còn có thể sử dụng option -15 (có nghĩa là SIGTERM) hay là option -2 (có nghĩa là SIGINT).

Về lệnh trap

trap [-lp] [[arg] sigspec ...]

Lệnh trap có thể "theo dõi" signal *được gửi đến command đang được thực hiện bên trong [arg] *

Ví dụ

trap "echo trapped." 2

Bạn hãy thử copy câu lện trên vào shell, sau đó Ctrl+C xem, khi đó ở terminal sẽ hiện lên dòng chữ "trapped."
Câu lệnh trên có nghĩa là:

Thực hiện câu lệnh "echo trapped." khi nhận được signal 2 (ở đây có nghĩa là SIGINT, hay tương đương với việc ta ấn Ctrl+C)

Để xem ngoài 2 ra thì còn những SIGNAL nào khác thì chúng ta dùng option -l.

Fix: Nhờ góp ý của bạn @LeManhCuong thì option trên list ra những signal của hệ thống và số thứ tự tương ứng chứ không phải những SIGNAL mà trap có thể sử dụng được

$trap -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
16) SIGSTKFLT   17) SIGCHLD     18) SIGCONT     19) SIGSTOP     20) SIGTSTP
21) SIGTTIN     22) SIGTTOU     23) SIGURG      24) SIGXCPU     25) SIGXFSZ
26) SIGVTALRM   27) SIGPROF     28) SIGWINCH    29) SIGIO       30) SIGPWR
31) SIGSYS      34) SIGRTMIN    35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+3
38) SIGRTMIN+4  39) SIGRTMIN+5  40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+8
43) SIGRTMIN+9  44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-7
58) SIGRTMAX-6  59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-2
63) SIGRTMAX-1  64) SIGRTMAX

Có tới tận 64 signal khác nhau có thể được sử dụng

Để kiểm tra xem có những process nào đang chạy mà đang được theo dõi bởi trap chúng ta dùng option -p

$ trap -p
trap -- 'echo trapped.' SIGINT
trap -- '' SIGTSTP
trap -- '' SIGTTIN
trap -- '' SIGTTOU

Ứng dụng lệnh trap trong thực tế

Lệnh trap này rất hữu ích khi ta dùng shell script, đặc biệt khi chúng ta có một xử lý rất dài, mà đột nhiên bị ấn Ctrl+C, thì có thể sử dụng trap để qui định xử lý trong trường hợp bị ngắt giữa chừng như vậy

Ví dụ đơn giản là mình có một đoạn script sau để kiểm tra dung lượng server, in ra file

#!/bin/bash

today=`date +%y%m%d`
dir=/usr/local/src/srvdf
fileA=`ls -tr ${dir} | tail -n 1`

ssh srv1 "echo ----srv1 disk free result---- ; df -h ; echo ''" | tee srvdf.${today}
ssh srv2 "echo ----srv2 disk free result---- ; df -h ; echo ''" | tee -a srvdf.${today}
ssh srv3 "echo ----srv3 disk free result---- ; df -h ; echo ''" | tee -a srvdf.${today}
ssh srv4 "echo ----srv4 disk free result---- ; df -h ; echo ''" | tee -a srvdf.${today}

mv srvdf.${today} ${dir}/srvdf.${today}

fileB=`ls -tr ${dir} | tail -n 1`

echo "----diff "${fileA} ${fileB}"----"
diff ${dir}/${fileA} ${dir}/${fileB}

Giờ nhỡ giữa chừng khi đang in mà có chuyện gì xảy ra thì temp file mình tạo ra sẽ bị nằm trên server đang ssh. Mình muốn nhỡ chuyện gì xảy ra nhu process shell bị kill, hay mình bị mất mạng mất session thì file temp sẽ tự động xoá đi. Để làm việc đó chỉ cần một dòng lệnh đơn giản

trap 'rm srvdf.${today} ; exit 1'  1 2 3 15

Kết luận

Các bạn có thể thấy trap như một dạng hook hay preprocessing vậy, rất dễ dùng.

Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

White

Hoàng Minh Trung

23 bài viết.
61 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Cùng một tác giả
White
19 1
Bài viết dịch từ http://arslan.io/tenusefultechniquesingo Sử dụng một GOPATH duy nhất Sử dụng đồng thời nhiều GOPATH sẽ không giúp cho hệ thống ...
Hoàng Minh Trung viết 2 năm trước
19 1
White
18 15
(Ảnh) Mục đích của bài viết là hướng dẫn cơ bản nhất cho những ai chưa biết về docker, môi trường thực hiện là mac OS. Chuẩn bị Cài đặt virtua...
Hoàng Minh Trung viết gần 3 năm trước
18 15
White
14 0
Bài viết dịch từ https://github.com/luciotato/golangnotes/blob/master/OOP.md Mục đích bài viết Học golang dễ dàng hơn với những kiến thức bạn đ...
Hoàng Minh Trung viết 2 năm trước
14 0
Bài viết liên quan
White
2 2
Bash script to fast serve Laravel project Lười gõ dòng lệnh quá nên tạo ra cái script để gõ nhanh :D laravelstart.sh /bin/bash if z "$1" ] ...
Vũ Hoàng Chung viết hơn 1 năm trước
2 2
White
5 0
Step 1. Download peco binary tại đây Lưu ý download binary phù hợp với OS của bạn. Vd: Ubuntu 64b https://github.com/peco/peco/releases Step 2....
Tran Duong viết hơn 3 năm trước
5 0
White
13 8
Tạo một lúc nhiều file hay directory Tạo một lúc nhiều directory với mkdir và dấu {} bash mkdir {log_1,log_2,log_3} (Ảnh) Tạo một lúc nhiều fi...
Trần Thành viết 3 năm trước
13 8
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


White
{{userFollowed ? 'Following' : 'Follow'}}
23 bài viết.
61 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!