

root service/timer/etc/systemd/system/<name>.<timer | service>로 파일을 만든다.$USER service/timer$HOME/.config/systemd/user/<name>.<timer | service>로 파일 만든다.ssh.service를 살벼 보면서, service 제작법을 본다.ssh.service의 위치는 /usr/lib/systemd/system/ssh.service에 있다.

Requires, Wants를 가진 유닛을 활성화하면, systemd는 첫 번째 유닛과 동시에 이들 모든 종속성들을 활성화한다.ssh.service와 같이 multi-user.target다음에 시작되도록 설정된 것도 있다. 이럴 경우는 After를 사용한다.
network.target, auditd.service가 실행되어야한다.

/usr/lib/systemd/system/network.target
After=network-pre.target/usr/lib/systemd/system/network-pre.target 에 존재하나.

Before에 명시된 Unit '이전에' 실행된다.
!/etc/ssh/sshd_not_to_be_run이 되어 있음! 때문에, 여기에 /etc/ssh/sshd_not_to_be_run 파일이 없어야 실행되는 조건
Requires는 의존 관계(强)Requires에 설정된 Unit의 목록이 하나라도 시작되지 않으면, 이 Unit은 실행되지 않는다.Requires에 설정한다.
A을 B의 Requires 종속성을 갖게할 시,RequiredBy=B 로 할 것Requires를 추가할 필요 XWants는 의존 관계(弱)Wants는 의존관계는 있지만 설령 서비스가 시작되지 않더라도, 현재 실행되는 Unit 서비스 실행에 영향 XRequires보다는 약하다.
A을 B의 Wants 종속성을 갖게할 시,WantedBy=B 로 할 것Wants를 추가할 필요 XRequisite의 유닛의 '상태'를 점검한다.Requisite의 유닛이 활성화되어 있지 않으면, 현재 유닛을 활성화 XConflicts의 유닛을 비활성화 시킨다.XXX.service 이므로, [Service] 섹션이 있어야한다.XXX.socket이라면, [Socket] 섹션이 있어야한다./usr/lib/systemd/system/ssh.service)의 [Service] 섹션

| Type 값 | 설명 |
|---|---|
| simple | Default. 프로세스가 실행할 때 ExecStart에 있는 값이 main 프로세스라는 것 의미 즉, fork 되지 않는다. |
| forking | ExecStart에서 시작된 프로세스는 서비스의 주요 프로세스가 되는 하위 프로세스를 생성한다. 부모 프로세스는 시작이 완료되면 종료된다. 즉, 서비스는 fork되고, systemd는 처음 서비스 프로세스가 종료될 것으로 기대한다. 종료가 되자마자 systemd는 해당 서비스가 준비가 된 것으로 추정한다. |
| oneshot | simple과 유사하지만, '서비스 프로세스가 멈출 때' 사실상, 그 프로세스는 완전히 종료한다. 이런 Type을 위해, RemainAfterExit=yes 라는 옵션을 두어 프로세스가 종료되더라도 systemd가 여전히 서비스가 활성화된 것으로 간주할 수 있다. |
| dbus | simple과 유사하지만, 결과 단위는 main 프로세스가 D-Bus라는 이름을 얻은 후에야 시작 서비스가 준비되면 D-bus(Desktop Bus)에 자신을 등록한다. |
| notify | (지연 역할) simple과 유사하지만, 서비스가 준비 되면, sd_notify()함수를 통해 systemd에 맞게 메시지가 통지되고 시작된다. |
| idle | simple과 유사하지만, 이진 바이너리의 실제 실행은 모든 프로세스 작업이 끝날 때까지 지연됨으로써, 상태 출력을 서비스의 쉘 출력과 혼용되지 않게 도와준다. 즉, 활성화된 작업이 없을 때까지 systemd가 서비스를 시작하지 않도록 지시하는 것이다. 시스템을 계속 로딩하거나 서비스가 다른 서비스의 출력에 방해하는 일이 없도록 다른 서비스들이 시작할 때까지 서비스의 시작을 지연시키는 개념이다. 한번 서비스가 시작되면 서비스를 시작한 systemd 작업은 종료된다는 점에 유의한다. |
EnvironmentFile=-/etc/default/ssh가 있다./etc/default/ssh파일 /etc/init.d/ssh가 /bin/sh에 의해 sourced된다.
ExecStartPre=/usr/sbin/sshd -t가 있다.ExecStart=/usr/bin/python /home/pi/bin/myexec.py
[Service]
$ sudo systemctl reload 할 때, 실행하는 것ExecStartPre에서 지정한 동작을 다시 수행케 하고, $MAINPID에 HUP 시그널을 보낸다.ssh.service의 경우

systemctl 명령어 참고
service 파일을 수정하면 systemctl restartsystemctl reload를 해야하기 때문!!!
$ sudo systemctl restart 할 때, 하는 동작| Restart=Value | Description |
|---|---|
Restart=on-failure | Unit 프로세스가 어떤 문제로 exit != 0으로 종료/중지 될 경우 -> 그 서비스를 다시 시작하라는 의미 |
Restart=on-success | Unit 프로세스가 exit == 0 인 경우 -> 다시 그 서비스 시작하라는 의미 |


[Service]
KillMode=Process는 주 프로세스만 중지하라는 의미ssh.service의 경우

/usr/lib/systemd/system의 유닛 파일 /media.mount를 보면 /media tmpfs 파일 시스템을 나타낸다.[Unit]
Description=Media Directory
Before=local-fs.target
[Mount]
What=tmpfs
Where=/media
Type=tmpfs
Options=mode=755,nosuid,nodev,noexec
/media.mount에서 What은 tmpfs라고 되어 있는데, 이는 파일 시스템이 아직, 'device file'을 갖고있지 않기 때문이다.$ sudo systemctl enable, $ sudo systemctl disable과 관련[Install] 섹션을 무시한다.[Install] 섹션을 읽는다.sshd.service유닛을 가동하면, systemd는 multi-user.target의 WantedBy 종속성을 본다./etc/systemd/system)에서 multi-user.target.wants/sshd/service 경로의 심볼릭 링크를 만든다.

$ sudo systemctl enable 명령어로 Unit을 enable할 때, 등록에 필요한 유닛을 지정한다./etc/systemd/system/지명.target.wants에 들어간다.default.targetWantedBy=default.targetAlias에 등록한 이름으로 링크 파일 생성 X
systemd --user로 작성된 서비스/타이머를 대상으로 한 것systemd --system으로 작성한 서비스도 똑같다./etc/systemd/system/rsync_sstate.service, WantedBy=defulat.target$ sudo systemctl enable rsync_sstate.service/etc/systemd/ssytem/default.target.wants에 rsync_sstate.service 심볼릭 링크 생성됨multi-user.targetssh.service의 위치: /usr/lib/systemd/system/ssh.servicessh.service에서 [Install] 내용
/etc/systemd/system/multi-user.target.wants/에 ssh.service 소프트링크 생성/etc/systemd/system/에 systemd가 알아먹을 수 있게, Alias=sshd.service대로
multi-user.target.wants 내용
$ sudo systemctl enable 'alias' 접근 가능[Alias Name].service
$OPTIONS, $MAINPID 등이 있다.$OPTIONS: systemctl로 유닛을 활성화시킬 때, sshd로 전송할 수 있는 옵션들$MAINPID: 서비스에 대한 프로세스를 추적한 것%n: 현재의 유닛 명getty프로세스 처럼, 한 가지 서비스에 대해 여러 개의 복사본을 생성하기 위해, 하나의 유닛 파일을 매개변수화할 수 있다.@ 표시를 넣는다.getty의 경우, getty@.service라는 이름의 유닛 파일을 생성한다.getty@tty1과 getty@tty2처럼, 유닛들을 참조할 수 있게 해준다.@ 다음에 무엇이 오든지 instance로 불린다. 그리고 유닛 파일을 처리할 때, systemd는 %I specifier를 인스턴스로 확장한다. 이것이 systemd를 실행하는 대부분의 배포판에 포함되어 있는 getty@.service유닛 파일과 함께 동작하는 것을 볼 수 있다.%H: 현재의 호스트 명$HOME/workspace/systemd_service/helloworld/helloworld.sh 스크립트 제작# ==== helloworld.sh ==== #
#!/bin/bash
echo "Hello World!"
/etc/systemd/system/exec_helloworld.service 제작

$ sudo systemctl exec_helloworld.service
4-1. $ sudo systemctl exec_helloworld.service 로 조희
$ sudo systemctl exec_helloworld.service
● exec_helloworld.service - Simple execute helloworld script service
Loaded: loaded (/etc/systemd/system/exec_helloworld.service; disabled; vendor preset: enabled)
Active: inactive (dead)
7월 23 16:55:22 dhyang systemd[1]: Started Simple execute helloworld script service.
7월 23 16:55:22 dhyang helloworld.sh[1051298]: Hello World!
7월 23 16:55:22 dhyang systemd[1]: exec_helloworld.service: Succeeded.
pid: 1051298로 helloworld.sh가 실행되어 Hello World!를 stdout으로 출력4-2. $ journalctl -r -u exec_hellowrold.service로 조희
➜ default.target.wants journalctl -r -u exec_helloworld.service
-- Logs begin at Wed 2021-06-02 16:36:14 KST, end at Fri 2021-07-23 17:35:40 KST. --
7월 23 17:34:54 dhyang systemd[1]: /etc/systemd/system/exec_helloworld.service:6: Failed to parse service type, ignoring: Simple
7월 23 16:55:23 dhyang systemd[1]: /etc/systemd/system/exec_helloworld.service:6: Failed to parse service type, ignoring: Simple
7월 23 16:55:22 dhyang systemd[1]: exec_helloworld.service: Succeeded.
7월 23 16:55:22 dhyang helloworld.sh[1051298]: Hello World!
7월 23 16:55:22 dhyang systemd[1]: Started Simple execute helloworld script service.
7월 23 16:55:22 dhyang systemd[1]: /etc/systemd/system/exec_helloworld.service:6: Failed to parse service type, ignoring: Simple
7월 23 16:55:11 dhyang systemd[1]: /etc/systemd/system/exec_helloworld.service:6: Failed to parse service type, ignoring: Simple
7월 23 16:55:02 dhyang systemd[1]: /etc/systemd/system/exec_helloworld.service:6: Failed to parse service type, ignoring: Simple
7월 23 16:54:58 dhyang systemd[1]: /etc/systemd/system/exec_helloworld.service:6: Failed to parse service type, ignoring: Simple
7월 23 16:53:53 dhyang systemd[1]: /etc/systemd/system/exec_helloworld.service:6: Failed to parse service type, ignoring: Simple
7월 23 16:53:36 dhyang systemd[1]: exec_helloworld.service: Succeeded.
7월 23 16:53:36 dhyang helloworld.sh[1044548]: Hello World!
7월 23 16:53:36 dhyang systemd[1]: Started Simple execute helloworld script service.
7월 23 16:53:36 dhyang systemd[1]: /etc/systemd/system/exec_helloworld.service:6: Failed to parse service type, ignoring: Simple
7월 23 16:53:33 dhyang systemd[1]: /etc/systemd/system/exec_helloworld.service:6: Failed to parse service type, ignoring: Simple
7월 23 16:53:33 dhyang systemd[1]: /etc/systemd/system/exec_helloworld.service:6: Failed to parse service type, ignoring: Simple
test1.target/etc/systemd/systemtest1.target/etc/systemd/system/test1.target
test2.target/etc/systemd/systemtest2.target/etc/systemd/system/test2.target
Wants 종속성에 test1.target을 걸어둔다.$ sudo systemctl start test2.target

test2.target의 Wants에 의해 systemd는 test1.target을 활성화한다.[Install] 섹션을 갖고 있다면, 이를 활성화시키기 전에 유닛을 "이용 가능하게" 한다.$ sudo systemctl enable <unit>
$ system sudo systemctl status test1.target
● test1.target - test 1
Loaded: loaded (/etc/systemd/system/test1.target; static; vendor preset: enabled)
Active: active since Mon 2021-09-27 14:43:09 KST; 15s ago
Sep 27 14:43:09 ubuntu-linux-20-04-desktop systemd[1]: Reached target test 1.
$ system sudo systemctl status test2.target
● test2.target - test 2
Loaded: loaded (/etc/systemd/system/test2.target; static; vendor preset: enabled)
Active: active since Mon 2021-09-27 14:43:09 KST; 20s ago
Sep 27 14:43:09 ubuntu-linux-20-04-desktop systemd[1]: Reached target test 2.
/etc/systemd/systemtest1.target/etc/systemd/system/test1.target
/etc/systemd/systemtest2.target/etc/systemd/system/test2.target
[Install] 부분에 등록시켰기 때문에 systemctl enable 해야 이 명령이 먹힌다.
$ sudo systemctl enable test1.target
/etc/systemd/system/에 'test2.target.wants' 에 symlink test1.target 생성
$ sudo systemctl status test1.target
● test1.target - test 1
Loaded: loaded (/etc/systemd/system/test1.target; enabled; vendor preset: >
Active: inactive (dead)
Sep 27 15:05:37 ubuntu-linux-20-04-desktop systemd[1]: Reached target test 1.
$ sudo systemctl status test2.target
● test2.target - test 2
Loaded: loaded (/etc/systemd/system/test2.target; static; vendor preset: >
Active: inactive (dead)