Làm cách nào để chạy tập lệnh với systemd ngay trước khi tắt máy?


58

Tôi cần phải làm gì trong [install]phần này, để systemd chạy /home/me/so.plngay trước khi tắt máy và cả trước khi /proc/self/net/devbị phá hủy?

[Unit]
Description=Log Traffic

[Service]
ExecStart=/home/me/so.pl

[Install]
?

Câu trả lời:


66

Giải pháp được đề xuất là chạy đơn vị dịch vụ như một dịch vụ bình thường - hãy xem [Install]phần này. Vì vậy, mọi thứ phải được suy nghĩ ngược lại, phụ thuộc quá. Bởi vì thứ tự tắt máy là thứ tự khởi động ngược. Đó là lý do tại sao kịch bản phải được đặt vào ExecStop=.

Giải pháp sau đây có hiệu quả với tôi:

[Unit]
Description=...

[Service]
Type=oneshot
RemainAfterExit=true
ExecStop=<your script/program>

[Install]
WantedBy=multi-user.target

RemainAfterExit=truelà cần thiết khi bạn không có một ExecStarthành động.

Sau khi tạo tập tin, hãy chắc chắn systemctl daemon-reloadsystemctl enable yourservice --now.

Tôi vừa nhận được nó từ IRC hệ thống, các khoản tín dụng sẽ đến mezcalero.


6
Tại Ubuntu 16.04, bạn phải có một ExecStart=/bin/true.
cháu gái

3
Giả định của tôi về TẠI SAO RemainAfterExit=true là bắt buộc khi không có ExecStartlà vì systemdsẽ không cố chạy ExecStopnếu nó nghĩ rằng dịch vụ không chạy. RemainAfterExit=truenguyên nhân systemdđể tin rằng dịch vụ đang chạy, do đó khiến nó chạy ExecStopkhi tắt máy.
Felipe Alvarez

1
Có cách nào để đảm bảo tập lệnh này sẽ chạy và hoàn thành trước khi phiên người dùng và quy trình người dùng bị chấm dứt không?
richmb

@richmb Không hề. Từ các tài liệu :Note that it is usually not sufficient to specify a command for this setting that only asks the service to terminate (for example, by queuing some form of termination signal for it), but does not wait for it to do so.
svenwltr

Tôi đã thử điều này và nhiều lần lặp khác nhau trên nó nhưng nó không hoạt động trên Debian Stretch.
2rs2ts

8

Theo như tôi có thể thấy điều này làm những gì tôi cần (nhưng tôi không biết chính xác tại sao).

[Unit]
Description=Log Traffic
DefaultDependencies=no
Before=shutdown.target reboot.target halt.target


[Service]
ExecStart=/usr/local/bin/perl /home/me/log_traffic.pl --stop
Type=oneshot

3
Nó xảy ra vì 2 điều: 1) DefaultDependencies = no làm cho nó bỏ qua tất cả các phụ thuộc và chạy "lúc đầu" khi bắt đầu và "cuối cùng" khi dừng, luôn luôn tôn trọng các mệnh đề "Trước" và "Sau". 2) Nó có một mệnh đề Before về các mục tiêu tắt máy / khởi động lại / tạm dừng, vì vậy nó sẽ chạy ngay trước khi tắt máy / khởi động lại / tạm dừng (vì chúng chỉ chạy khi dừng nên nó xảy ra để làm những gì bạn muốn).
RDP

Bạn có thể muốn thêm kexec.targetvào bit Before
hanetzer

Điều này không hiệu quả với tôi
Bug Killer

Tôi không thấy cách này sẽ hoạt động trừ khi bạn cũng thêm WantedBy=shutdown.target reboot.target halt.targetvào [Unit]phần. Before=& After=không thay đổi phụ thuộc.
rsaw

1
@FelipeAlvarez: Tôi đã xóa nhận xét của mình.
sid_com

7
  • Để chạy một dịch vụ ngay trước khi bắt đầu bất kỳ dịch vụ khởi động lại / shutdown / halt / kexec nào (tức là trong giây phút cuối cùng trước khi hệ thống tập tin gốc trở thành chỉ đọc lại), hãy sử dụng cấu hình dịch vụ này:

    [Unit]
    Description=Save system clock on shutdown
    DefaultDependencies=no
    After=final.target
    
    [Service]
    Type=oneshot
    ExecStart=/usr/lib/systemd/scripts/fake-hwclock.sh save
    
    [Install]
    WantedBy=final.target
    

    Kích hoạt nó với:

    systemctl enable my_service.service
    
  • Để chạy tập lệnh ngay trước khi khởi động lại / shutdown / halt / kexec thực tế (khi bạn không thể ghi vào hệ thống tập tin gốc, vì nó được đọc lại chỉ đọc) hãy thêm tập lệnh này vào /usr/lib/systemd/system-shutdownthư mục.

    Ngay lập tức trước khi thực hiện hệ thống thực tế tạm dừng / poweroff / restart / kexec systemd-shutdown sẽ chạy tất cả các thực thi trong / usr / lib / systemd / system-shutdown / và truyền một đối số cho chúng: hoặc "tạm dừng", "poweroff", "khởi động lại "Hoặc" kexec ", tùy thuộc vào hành động đã chọn. Tất cả các tệp thực thi trong thư mục này được thực thi song song và việc thực thi hành động không được tiếp tục trước khi tất cả các tệp thực thi kết thúc.

Cũng thấy:

https://www.freedesktop.org/software/systemd/man/bootup.html

https://www.freedesktop.org/software/systemd/man/systemd-halt.service.html


1
Tôi muốn thực hiện một cái gì đó càng gần càng tốt sau khi bắt đầu khởi động lại, trước khi final.target. Lý tưởng nhất tôi muốn rằng đó là điều đầu tiên được thực hiện sau khi người dùng làm $ sudo reboot.
Jaime Hablutzel

5

Tôi không hoàn toàn chắc chắn nhưng tôi không nghĩ bạn cần phần cài đặt mặc dù tôi đã thêm nó một cách rõ ràng. Tôi cũng không kiểm tra nhưng tôi nghĩ nó sẽ giúp bạn bắt đầu:

[Unit]
Description=Log Traffic
Requires=network.target
After=network.target
Before=shutdown.target
DefaultDependencies=no

[Service]
ExecStart=/home/me/so.pl
Type=oneshot
RemainAfterExit=yes

[Install]
WantedBy=shutdown.target

Khi tôi thử điều này, kịch bản sẽ được thực thi ngay sau khi bắt đầu (khởi động).
sid_com

@sid_com Sau khi đọc thread.gmane.org/gmane.comp.sysutils.systemd.devel/4515/, hãy thử thêm DefaultDependencies = no và có thể xóa phần cài đặt. Nếu không, nó có thể giúp từ xa các dòng sau / yêu cầu.
Ulrich Dangel
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.