Có thể launchd chạy các chương trình thường xuyên hơn cứ sau 10 giây không?


8

Tôi có một số dịch vụ như thế này mà tôi muốn chạy gần như ngay lập tức sau khi các tệp được sửa đổi.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC -//Apple Computer//DTD PLIST 1.0//EN
http://www.apple.com/DTDs/PropertyList-1.0.dtd>
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>test</string>
    <key>ProgramArguments</key>
    <array>     
        <string>say</string>
        <string>a</string>
    </array>
    <key>WatchPaths</key>
    <array>
        <string>/Users/username/Desktop/</string>
    </array>
</dict>
</plist>

Ngay cả khi ThrptionInterval được đặt thành 1 hoặc 0, chúng chỉ chạy tối đa cứ sau 10 giây.

9/9/12 4:57:05.457 PM com.apple.launchd.peruser.501[138]: (test) Throttling respawn: Will start in 7 seconds
9/9/12 4:57:09.541 PM com.apple.launchd.peruser.501[138]: (test) Throttling respawn: Will start in 3 seconds

man launchd.plist chỉ nói rằng các chương trình không chạy hơn 10 giây theo mặc định, nhưng không đề cập đến việc ThrottInterval không thể được đặt bên dưới mức đó.

ThrottleInterval <integer>
This key lets one override the default throttling policy imposed on jobs by launchd.
The value is in seconds, and by default, jobs will not be spawned more than once
every 10 seconds.  The principle behind this is that jobs should linger around just
in case they are needed again in the near future. This not only reduces the latency
of responses, but it encourages developers to amortize the cost of program invoca-
tion.

Bạn có thể giữ chương trình hoặc tập lệnh chạy trong 10 giây và theo dõi các thay đổi mỗi giây:

#!/bin/bash

start=$(date +%s)
prev=

until (( $(date +%s) >= $start + 10 )); do
    new=$(stat -f %m ~/Desktop/)
    [[ $prev != $new ]] && say a
    prev=$new
    sleep 1
done

Hoặc tương tự trong Ruby:

#!/usr/bin/env ruby

start = Time.now
prev = nil

until Time.now >= start + 10
  current = File.mtime("#{ENV['HOME']}/Desktop/")
  `say a` if current != prev
  prev = current
  sleep 1
end

Nhưng có cách nào để bỏ qua hoặc giảm thời gian giới hạn? Nó cũng áp dụng cho các hành động thư mục.

Câu trả lời:


9

Không có cách nào để bỏ qua hoặc giảm thời gian giới hạn.

Tài liệu của Apple liên quan đến việc tạo Launchd Jobs nêu rõ như sau:

Quan trọng Nếu trình nền của bạn tắt quá nhanh sau khi được khởi chạy, launchd có thể nghĩ rằng nó đã bị hỏng. Daemon tiếp tục hành vi này có thể bị đình chỉ và không được khởi chạy lại khi có yêu cầu trong tương lai. Để tránh hành vi này, không tắt ít nhất 10 giây sau khi khởi chạy.

Chương trình hoặc tập lệnh của bạn cần tiếp tục chạy trong ít nhất 10 giây. Cân nhắc thực hiện một vòng lặp để kiểm tra ngày sửa đổi tệp trong mười giây qua, ngủ trong mười giây và lặp lại.

Ngoài ra, bạn có thể xem các file cụ thể bằng cách sử dụng kqueue hoặc FSEvents API. Câu hỏi StackOverflow này có thể hữu ích, file cấp thông báo thay đổi hệ thống tập tin trong Mac OS X .


2

Bạn có thể giữ tập lệnh của mình chạy trong một vòng kiểm tra các tệp đã sửa đổi thay vì thoát khi hoàn thành. Ngủ một vài giây sau khi kiểm tra các tập tin đã sửa đổi. Nếu nó tìm thấy các tập tin sửa đổi, tiếp tục với tập lệnh. Nếu không, hãy ngủ lại.

Sau đó, launchd bắt đầu tập lệnh của bạn cứ sau x phút trong trường hợp lần chạy trước chết. Viết mã phần đầu tập lệnh của bạn để kiểm tra xem một phiên bản khác có đang chạy hay không và nếu có, hãy tự thoát.


launchd dường như không bắt đầu một phiên bản khác nếu phiên bản trước vẫn đang chạy.
Lri

launchd sẽ không khởi chạy nhiều phiên bản của cùng một vé công việc.
Graham Miln

1

Nếu bạn cần bắt đầu một tập lệnh thường xuyên hơn cứ sau 10 giây, thì có thể tốn kém về mặt "forking" (đọc: phân bổ bộ nhớ, bắt đầu các quy trình mới, v.v.).

Do đó, trong trường hợp này là tốt nhất để viết " trình nền " của riêng bạn (chương trình, những gì chạy trong nền)

Tôi khuyên bạn nên sử dụng ngôn ngữ "có khả năng hơn" là BASH (sở thích của tôi là "perl", nhưng ruby ​​cũng không sao) vì một trình nền tốt xử lý thời gian chờ, báo thức, v.v. - những thứ quá khó thực hiện trong bash thuần túy. (Tất nhiên, daemon cũng có thể chạy các tập lệnh bash của bạn - nếu cần). Những điều cơ bản là:

  • kịch bản những gì đang chạy vô tận và chờ đợi một sự kiện. Sự kiện này có thể là một số đầu vào mạng, hoặc bộ đếm thời gian đơn giản hoặc bất cứ thứ gì như thế. Khi sự kiện đến (ví dụ trạng thái chờ kết thúc), tập lệnh sẽ thực hiện những gì bạn muốn và chu trình lặp lại.

Trong thế giới perl đã tồn tại các mô-đun, điều chỉnh kịch bản của bạn là quá trình "daemon", ví dụ Proc :: Daemon . Tôi không có kinh nghiệm với ruby, nhưng bài viết này có thể giúp bạn.

Bạn có thể bắt đầu quá trình trình nền của mình thông qua Launchd khi khởi động hệ thống hoặc từ ứng dụng tự động hóa khi bạn đăng nhập hoặc từ Terminal bằng tay.

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.