Làm cách nào để làm cho dịch vụ systemd của tôi chạy qua người dùng cụ thể và bắt đầu khởi động?


133

Tôi vừa nâng cấp từ máy chủ Ubuntu 14 lên phiên bản 15. Tôi gặp khó khăn khi tập lệnh khởi động của tôi hoạt động sau khi nâng cấp và đọc systemd là mặc định mới. Tôi ở xa một chuyên gia linux, vì vậy xin hãy dễ dàng với tôi :-)

Đây là những gì kịch bản mới nổi của tôi trước đây:

description "NZBGet upstart script"

setuid robert
setgid robert

start on runlevel [2345]
stop on runlevel [016]

respawn

expect fork

script
    exec nzbget -D
end script

pre-stop script
    exec nzbget -Q
end script

Dựa trên trang wiki mới bắt đầu , tôi đã sử dụng các bảng được cung cấp ở đó để ánh xạ mọi thứ gần nhất có thể trong tệp dịch vụ systemd mới của mình:

[Unit]
Description=NZBGet Service

[Service]
Type=forking
ExecStart=/usr/local/bin/nzbget -D
ExecStop=/usr/local/bin/nzbget -Q
Restart=on-failure

Tập tin này được đặt tại /home/robert/.config/systemd/user/nzbget.service. Để bắt đầu dịch vụ theo cách thủ công, tôi đã và đang làm:

$ systemctl --user start nzbget

Điều này làm việc tuyệt vời. Tuy nhiên, khi tôi đăng xuất khỏi phiên SSH, dịch vụ sẽ tắt. Ngoài ra, nó không bắt đầu khi khởi động hoặc đăng nhập người dùng. Tôi muốn nó hoạt động giống như một dịch vụ mới bắt đầu: Tôi muốn nó bắt đầu lúc khởi động, chạy liên tục và như một người dùng cụ thể.

Tôi cần làm gì để có được cấu hình này?

Câu trả lời:


164

Vấn đề đầu tiên

Bạn có thể chỉ định các chỉ thị User=Group=trong [Service]phần của tệp đơn vị.

Vấn đề thứ hai

Để làm cho dịch vụ chạy khi khởi động, bạn không nên đặt nó vào thư mục nhà của bạn. Thay vào đó, đặt nó dưới /etc/systemd/system/. Đây là thư mục được sử dụng bởi quản trị viên hệ thống (tức là bạn) để thêm các dịch vụ toàn hệ thống mới.

Các thư mục khác bao gồm:

  • /usr/lib/systemd/system/có nghĩa là cho các gói muốn cài đặt các tệp đơn vị, mặc dù trong Debian và Ubuntu, thư mục thực sự là /lib/systemd/system/do các thư mục binlibthư mục khác nhau chưa được hợp nhất thành một /usr/tiền tố hợp nhất .
  • /usr/local/systemd/system/ là để cài đặt các đơn vị bởi các gói biên dịch cục bộ.

Kiểm tra đơn vị

Khi tệp đơn vị ở vị trí thích hợp, bạn có thể thử khởi động thiết bị ngay lập tức bằng cách nhập systemctl start <UNIT_FILENAME>như bình thường. Nó sẽ hoạt động mà không cần phải nhập đường dẫn đầy đủ của đơn vị. Phần mở rộng cũng không phải được chỉ định nếu nó .service.

Kích hoạt thiết bị

Trước khi bạn có thể kích hoạt đơn vị của mình, bạn cần thêm một [Install]phần, theo đó bạn nên thêm chỉ thị WantedBy=multi-user.target. Lệnh này chỉ định giai đoạn của quá trình khởi động trong đó dịch vụ sẽ được khởi động (nếu nó được kích hoạt). multi-user.targetlà phù hợp cho hầu hết các dịch vụ.

Khi thông tin đó được thêm vào, bạn có thể sử dụng systemctl enable <UNIT_FILENAME>, cho phép thiết bị, làm cho systemd từ bây giờ tự động khởi động nó trong khi khởi động ở giai đoạn được chỉ định.


Điều này đã làm việc. Tôi đã phải xác định đường dẫn tuyệt đối đến tên tệp dịch vụ trong systemctl enablelệnh, điều này ban đầu không rõ ràng đối với tôi. Cũng cho phép tôi một số cảnh báo về một [Install]phần bị thiếu . Tôi đã bỏ qua nó, nhưng tôi không chắc liệu nó có ảnh hưởng đến khả năng bắt đầu khi khởi động hay không.
void.pulum

2
Các Installcảnh báo đã thực sự thực sự quan trọng. Nó không khởi động khi khởi động mà không WantedBy=multi-user.targetthuộc [Install]phần. Sau khi thêm nó vào .servicetập tin, sau đó bạn có thể enablenó.
void.pulum

4
Tôi xin lỗi về việc để lại câu trả lời không được giám sát trong một thời gian dài như vậy. Tôi đã sửa vị trí mà tệp đơn vị sẽ đi, thêm thông tin còn thiếu về [Install]phần này. Hy vọng nó bây giờ hữu ích hơn cho bất cứ ai tìm kiếm nó.
Yamaho

5
Điều này trở nên dễ dàng hơn nhiều khi tên người dùng được tạo khuôn mẫu, tức là dịch vụ của bạn được xác định bằng tên tệp theo định dạng something@.servicesau đó enablegiống như something@username.servicecài đặt User=%icó nghĩa là người dùng không bị mã hóa cứng và nhiều người dùng có thể sử dụng cùng một định nghĩa. Một ví dụ.
Walf

1
Nó sẽ bắt đầu nếu tôi đặt nó dưới /etc/systemd/user/?
Khurshid Alam

46

Bạn có thể quan tâm đến việc sử dụng chức năng "người dùng kéo dài" của systemd. Nó được kích hoạt thông qua loginctl enable-linger USERNAME.

Nó khiến trình quản lý dịch vụ riêng biệt cho người dùng tương ứng được khởi động khi khởi động, do đó, các đơn vị do người dùng xác định của bạn ~/.config/systemd/usersẽ được chọn và xử lý tại thời điểm khởi động và tắt máy theo cấu hình dịch vụ của bạn.

Bạn cũng có thể sử dụng systemctl --userđể quản lý và định cấu hình (các) dịch vụ, dịch vụ này sẽ hoạt động trên trình quản lý dịch vụ của người dùng của bạn chứ không phải của một trong hệ thống.


6
systemctl --userlà một phát hiện tuyệt vời Cảm ơn!
Anwar

@byteborg Có lẽ bạn có thể đóng góp cho unix.stackexchange.com/questions / 409900 / Cách ? Tôi cần sự phụ thuộc vào PostgreSQL trong dịch vụ kéo dài người dùng, nhưng cơ sở dữ liệu vẫn là dịch vụ hệ thống, không phải của người dùng.
Michał F

1
Khi các dịch vụ đang chạy, có kỹ thuật nào có thể cho phép người dùng xem nhật ký của dịch vụ không? Người dùng không có đặc quyền sẽ không thể truy cập / var / log / syslog.
MPR

2
Lưu ý rằng systemctl --userdường như không hoạt động cho các phiên SSH.
Mark K Cowan

2
Nên là giải pháp được chấp nhận
Drew
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.