Được bash
xây dựng nguyên chất , không có lõi
Tôi thấy rằng giải pháp này làm việc tại bash
dựa vào một built-in lệnh mà không gọi một thực thi bên ngoài. Nó hoạt động trên hệ thống mà cuối cùng thậm chí không được cài đặt coreutils [ 1 ]
YourCommand & read -t 300 ; kill $! # 1st version
YourCommand & read -t 300 || kill $! # 2nd version
Giải thích : như bình thường khi bạn gửi một lệnh trong nền với &
, PID của nó được lưu trữ trong các biến nội bộ $!
(hiện diện trong phiên bản hiện đại của dash
, csh
, bash
, tcsh
, zsh
...).
Điều gì thực sự làm cho sự khác biệt giữa các vỏ là sự hiện diện của các built-in lệnh read
[ 2 ] và các tùy chọn -t
. Trong phiên bản đầu tiên, nếu người dùng sẽ không hoàn thành một dòng đầu vào trước khi số giây được chỉ định, lệnh sẽ bị chấm dứt và mã trả về lỗi sẽ được tạo.
-t TIMEOUT Nguyên nhân đọc hết thời gian và trả về thất bại nếu một dòng đầu vào hoàn chỉnh không được đọc trong vòng TIMEOUT giây.
Phiên bản thứ hai hoạt động như phiên bản thứ 1 nhưng bạn có thể hủy bỏ thời gian chờ giết chỉ bằng cách nhấn enter.
Thật vậy, toán tử hoặc ||
thực thi kill
câu lệnh chỉ khi read
lệnh thoát với mã trả về khác 0, khi hết thời gian chờ. Nếu bạn nhấn entertrước thời điểm đó, nó sẽ trả về 0 và nó sẽ không giết lệnh trước đó của bạn.
Giải pháp Coreutils [ 1 ]
Khi coreutils có mặt trên hệ thống của bạn và bạn không cần phải tiết kiệm thời gian và tài nguyên để gọi một chương trình bên ngoài, timeout
và sleep
cả hai đều là những cách hoàn hảo để đạt được mục tiêu của bạn.
timeout
Việc sử dụng timeout
là đơn giản.
Cuối cùng, bạn có thể cân nhắc sử dụng -k
tùy chọn để gửi tín hiệu tiêu diệt bổ sung nếu lần đầu tiên thất bại.
timeout 5m YourCommand # 3rd version
sleep
Với sleep
bạn có thể sử dụng tưởng tượng của bạn hoặc lấy một số cảm hứng [ 3 ] . Lưu ý rằng bạn có thể để lệnh của bạn ở chế độ nền hoặc ở nền trước (ví dụ: top
thường cần phải ở phía trước).
YourCommand & sleep 5m; kill $! # 4th Background
YourCommand & pid=$! ; (sleep 5m; kill $pid;) & # 5th Background
bash -c '(sleep 5m; kill $$) & exec YourCommand' # 6th Foreground
(cmdpid=$BASHPID; (sleep 5m; kill $cmdpid) & exec YourCommand) # 7th Foreground
Giải thích
- Trong phiên bản thứ 4, bạn thực hiện trong nền
YourCommand
sau đó shell của bạn sleep
trong 5 minuites. Khi nó được hoàn thành, quá trình nền cuối cùng ( $!
) sẽ bị giết. Bạn dừng vỏ của bạn.
-
Trong phiên bản thứ 5 thay vì bạn thực thi trong nền
YourCommand
và bạn lưu trữ ngay lập tức PID đó trong biến $pid
. Sau đó, bạn thực hiện trong một giấc ngủ ngắn trong 5 phút và lệnh hệ quả của nó sẽ giết chết bộ lưu trữ đó. Vì bạn đã gửi nhóm lệnh này trong nền nên bạn không dừng trình bao của mình. Bạn cần lưu trữ PID trong một biến vì giá trị của $!
có thể được cập nhật bằng cách thực hiện cuối cùng của một chương trình khác trong nền. Nói một cách đơn giản, bạn tránh được rủi ro để giết sai quy trình hoặc không có quy trình nào cả.
- Trong phiên bản thứ 6, nó được gọi là bash shell mới sẽ tự sát sau 5 phút
$$
, sau đó nó được thực thi lệnh của bạn vẫn ở phía trước.
- Trong phiên bản thứ 7, nó được gọi một lớp
()
con lưu trữ PID của nó trong một biến ( cmdpid
) và tự giết mình với một lớp con khác được gửi trong thực thi nền, sau đó chạy YourCommand ở phía trước.
Tất nhiên trong mỗi phiên bản, bạn có thể gửi tín hiệu tiêu diệt bạn cần, từ mức mặc định đến cực trị kill -9
, chỉ được sử dụng khi thực sự cần thiết.
Người giới thiệu
- [ 1 ] Coreutils
- [ 2 ] Hướng dẫn cho người mới bắt đầu Bash
- [ 3 ] BashFAQ