Cách thích hợp để chạy script shell như một daemon


20

Tôi đang viết một kịch bản shell mà tôi muốn chạy như một daemon khi khởi động mà không sử dụng các công cụ bên ngoài như daemontools hoặc daemonize .


Linux Daemon Viết HOWTO

Theo Linux Daemon Writing HOWTO , một daemon thích hợp có các đặc điểm sau:

  • dĩa từ quá trình cha mẹ
  • đóng tất cả các file descriptor (ví dụ stdin, stdout, stderr)
  • mở nhật ký để viết (nếu được cấu hình)
  • thay đổi thư mục làm việc thành một liên tục (thường /)
  • Đặt lại mặt nạ chế độ tập tin (umask)
  • tạo ID phiên duy nhất (SID)

daemonize Giới thiệu

Các daemonize Giới thiệu đi xa hơn, nói rằng một daemon tiêu biểu thêm:

  • tách khỏi thiết bị đầu cuối điều khiển của nó (nếu có) và bỏ qua tất cả các tín hiệu đầu cuối
  • tách ra khỏi nhóm quy trình của nó
  • tay cầm SIGCLD

Làm thế nào tôi sẽ làm tất cả điều này trong một sh, dashhoặc bashkịch bản chỉ với công cụ Linux phổ biến?

Kịch bản sẽ có thể chạy trên càng nhiều phân phối càng tốt mà không cần phần mềm bổ sung, mặc dù Debian là trọng tâm chính của chúng tôi.


LƯU Ý: Tôi biết có rất nhiều câu trả lời trên mạng StackExchange khuyến nghị sử dụng nohuphoặc setsid, nhưng cả hai phương pháp này đều không giải quyết được tất cả các yêu cầu ở trên.


EDIT: Trang chủ daemon (7) cũng đưa ra một số gợi ý, mặc dù dường như có một số khác biệt giữa các SysVdaemon kiểu cũ và các kiểu mới hơn systemd. Vì khả năng tương thích với nhiều loại distro rất quan trọng, vui lòng đảm bảo câu trả lời làm rõ mọi khác biệt.



1
Cách "thích hợp" để tạo tập lệnh shell của riêng bạn là làm cho nó tự ghi nhật ký, cung cấp một phương thức để khởi chạy nó dưới dạng daemon, v.v. Những thứ như daemonvà những thứ khác là để chạy các tập lệnh shell tùy ý không có điều khoản để chạy như một daemon. Vì bạn là tác giả, hoàn toàn kiểm soát cách viết tập lệnh đó, làm cho nó có thể được khởi chạy từ tập lệnh systemfile hoặc rc.d. Bạn đã chỉ định "Đúng"!
Giàu

Câu trả lời:


16

Sử dụng systemd, bạn sẽ có thể chạy một kịch bản như một daemon bằng cách tạo một đơn vị đơn giản. Có rất nhiều tùy chọn khác nhau mà bạn có thể thêm nhưng điều này đơn giản như bạn có thể nhận được.

Nói rằng bạn có một kịch bản /usr/bin/mydaemon.

#!/bin/sh

while true; do
  date;
  sleep 60;
done

Bạn tạo một đơn vị /etc/systemd/system/mydaemon.service.

[Unit]
Description=My daemon

[Service]
ExecStart=/usr/bin/mydaemon
Restart=on-failure

[Install]
WantedBy=multi-user.target 

Để bắt đầu con quỷ bạn chạy

systemctl start mydaemon.service 

Để bắt đầu lúc khởi động, bạn kích hoạt nó

systemctl enable mydaemon.service

Nếu trên một hệ thống dựa trên hệ thống, mà phần lớn các bản phân phối Linux hiện nay, thì đây thực sự không phải là một công cụ bên ngoài. Điều tiêu cực là nó sẽ không hoạt động ở mọi nơi.


3
Mặc dù tôi thích cách tiếp cận systemd, OP nói "không có công cụ bên ngoài". Có những bản phân phối Linux chưa có systemd hoặc cho phép bạn sử dụng lựa chọn giữa systemd và một cái gì khác, ví dụ OpenRC.
Cristian Ciupitu

5
Đối với các distro sử dụng systemd, systemdkhông còn là "công cụ bên ngoài" hơn bash.
Alexander

7

Tôi có lẽ đang thiếu một cái gì đó ở đây; Tại sao chính xác sẽ không nohupthích hợp? Tất nhiên nó không đủ một mình , nhưng việc bổ sung nó có vẻ đơn giản.

#!/bin/bash

if [ "$1" = "DAEMON" ]; then
    # is this necessary? Add other signals at will (TTIN TTOU INT STOP TSTP)
    trap '' INT
    cd /tmp
    shift
    ### daemonized section ######
    for i in $( seq 1 10 ); do
        date
        sleep 5
    done
    #### end of daemonized section ####
    exit 0
fi

export PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/sbin:/usr/local/bin
umask 022
# You can add nice and ionice before nohup but they might not be installed
nohup setsid $0 DAEMON $* 2>/var/log/mydaemon.err >/var/log/mydaemon.log &

Theo như tôi có thể thấy:

  • đầu ra được chuyển hướng thích hợp (sử dụng / dev / null nếu cần)
  • cái ô được thừa kế
  • stdin chết ở cuối tập lệnh gốc
  • tập lệnh daemon.sh được sửa lại thành init(hoặc systemd)

Tôi có một cảm giác mạnh mẽ Tôi đang thiếu điều hiển nhiên. Downvote, nhưng xin vui lòng cho tôi biết đó là gì :-)


2
Tôi đã đề nghị một cái gì đó rất giống nhau. Tôi sử dụng nohupvới &và chuyển hướng I / O để khởi chạy một số Ctiện ích không phải daemon với sự bảo mật được thêm vào trong việc bọc nohuplệnh của bạn bên trong một su -c "nohup ... &" -s /bin/bash systemUserđể chạy daemon với tư cách là người dùng không có đặc quyền.
111 ---

4

Lệnh Linux screencó trong hầu hết các bản phân phối có thể tạo ra một tập lệnh shell. Tôi sử dụng nó thường xuyên. Đây là một ví dụ nhanh để bắt đầu, liệt kê và thoát khỏi phiên màn hình tách rời ...

# screen -dmS Session_Name  bash -c "while true; do date; sleep 60; done"

# screen -ls
There are screens on:
        8534.Session_Name       (04/04/2018 08:46:27 PM)        (Detached)

# screen -S Session_Name -X quit

2
screenkhông deamonize shell script. Nó chỉ chạy chúng trong thiết bị đầu cuối phân biệt và có thể tách ra khỏi thiết bị đầu cuối này (như rút bàn phím khỏi PC) mà không cần đóng phiên. Vì vậy, chương trình đang chạy trong thiết bị đầu cuối tách rời đang chạy trong nền. Do đó - tách chương trình trong nền.
Yurij Goncharuk
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.