2010-03-26 40 views
11

Tôi muốn bẫy một tín hiệu gửi từ Script-A.sh để Script-B.sh như vậy trong Script-A.sh tôi sử dụng lệnhLàm cách nào để gửi tín hiệu SIGINT từ tập lệnh đến tập lệnh? BASH

(Gửi SIGINT để Script-B.sh)
giết -2 $ PID_Script-B.sh

và trong Script-B.sh tôi bắt tín hiệu và gọi hàm sạch

bẫy 'sạch' 2

Nó không hoạt động, thay vì Script-B.sh bị giết ngay lập tức mà không thực hiện sạch !!

gì tôi nhận thấy cũng là nếu tôi muốn gửi SIGINT từ thiết bị đầu cuối cho bất kỳ kịch bản mà bẫy nó, một ctrl-c sẽ được đánh bắt một cách chính xác, nhưng không nếu tôi xác định các tín hiệu thông qua lệnh kill -2 $pid_of_script

Bất kỳ ý tưởng về sự khác biệt giữa hai phương pháp để gửi SIGINT (ctrl-c VS kill -2 $pid_of_script), và làm thế nào tôi có thể gửi một SIGINT từ một kịch bản khác?

Kính trọng,

Debugger

Trả lời

12

tôi đã có thể để tạo lại hành vi bạn báo cáo. Giả thuyết của tôi là vì tập lệnh đang chạy từ một vỏ không tương tác (dưới dạng tập lệnh con) mà SIGINT, là tín hiệu bàn phím, bị bỏ qua.

Từ info bash:

quá trình Bối cảnh là những người có quá trình nhóm ID khác với thiết bị đầu cuối của; các quy trình như vậy sẽ miễn nhiễm với các tín hiệu do bàn phím tạo ra.

Tôi đã tìm thấy rằng nếu bạn trapkill sử dụng tín hiệu khác như SIGUSR1 nó hoạt động.

thông tin bổ sung từ man bash:

lệnh

Non-BUILTIN chạy bởi bash có bộ xử lý tín hiệu thiết lập để các giá trị được thừa kế bằng vỏ từ cha của nó. Khi kiểm soát công việc không có hiệu lực, các lệnh không đồng bộ bỏ qua SIGINT và SIGQUIT ngoài các trình xử lý kế thừa này.

Nếu bash đang chờ đợi một lệnh để hoàn thành và nhận được một tín hiệu mà một cái bẫy đã được thiết lập, cái bẫy sẽ không được thực hiện cho đến khi lệnh hoàn thành.

Bất kỳ cái bẫy trên SIGCHLD được thực hiện cho mỗi đứa trẻ mà thoát.

+0

Đó bit đầu tiên từ bash (1) có vẻ như một lời giải thích. Ngoài ra, * zsh * có vẻ hoạt động tốt. –

+0

Xin lỗi vì câu trả lời muộn này. Bạn nói đúng, không phải tất cả các tín hiệu đều có thể bắt được cho trẻ em nhưng một số. SIGUSR1 làm việc cho tôi cũng như SIGTERM, nhưng không phải trong tất cả các phiên bản bash, gây ra tôi có một lỗi phân đoạn từ một kịch bản trong bash 3.00.16 khi cố gắng để gửi tín hiệu từ cha đến con trai !!! Lần khác sử dụng cùng một phiên bản nó sẽ chỉ bỏ qua tín hiệu mà không bắt nó (ở cấp độ trẻ em). Nhưng các phiên bản mới hơn hoạt động tốt và truyền chính xác tất cả các tín hiệu. Cảm ơn bạn rất nhiều vì đã giúp đỡ của bạn – Debugger

+0

ok. chạy scriptA shell script và gọi scriptB (nguồn nó) như "scriptB.sh param1 param2 .. paramN", theo cách đó, nó sẽ bắt sạch đối với Sig 2/INT –

0

Trong tập lệnh A: Chức năng bẫy trông giống như sau sẽ gọi hàm trap_mesg() trong scriptA.sh. KILL Signal (2/INTerrupt, 5/TERMinate-default). Tất cả, bạn phải làm là để có được các PID của một runing scriptB.sh trình/phiên một lần scriptB.sh được gọi từ scriptA.sh (nohup ... & sẽ cung cấp cho bạn hoặc sử dụng ps lệnh)

trap_mesg() 
{ 
#...do something here for script B.. 
# i.e. 
kill -2 PID_of_ScriptB.sh_running_process_session 
sleep 10; #just in case, not reqd though. 
#show using ps -eAf|grep "scriptB" ... if null means, scriptB is gone. user is happy now. 
#...before actually exiting out... 
#show script A is exiting out as ScriptB is dead already, time for scriptA now. 
#...do something here.. 
} 

##################################### 
## Trap signals : INT, TERM. catch ## 
##################################### 
#Set NULL/Blank value to trap_call. This variable will help in running trap_mesg only once during the life of this script. 
trap_call=""; 

trap 'if [ -z ${trap_call} ]; then trap_call="1"; trap_mesg ; fi' 2 15 
################################## 




Bây giờ, trong scriptB.sh, thực hiện tương tự/tương tự nhưng chỉ cho công việc bẫy scriptB (như gọi điện thoại sạch).

clean() 
{ 
echo "karoge seva to milega meva"; 
rm -fr /some/folder_file 
} 

trap_mesg() 
{ 
#...do something here JUST for script B trap message work.. 
# i.e. 
clean; 
#...do something here.. 
} 

##################################### 
## Trap signals : INT, TERM. catch ## 
##################################### 
#Set NULL/Blank value to trap_call. This variable will help in running trap_mesg only once during the life of this script. 
trap_call=""; 

trap 'if [ -z ${trap_call} ]; then trap_call="1"; trap_mesg ; fi' 2 15 
################################## 

Bằng cách này, bạn không cần phải nguồn/gọi scriptB.sh trong scriptA.sh như "scriptB.sh ...."

Các vấn đề liên quan