2020-03-04 09:35:06 +00:00
#!/usr/bin/env bash
2021-10-17 18:13:06 +02:00
# SPDX-License-Identifier: LGPL-2.1-or-later
2022-11-22 05:14:01 +01:00
# shellcheck disable=SC2016
2021-04-09 19:39:41 +02:00
set -eux
2018-11-26 21:16:27 +01:00
set -o pipefail
2023-05-16 19:09:13 +02:00
# shellcheck source=test/units/util.sh
. " $( dirname " $0 " ) " /util.sh
2022-11-15 21:52:10 +09:00
2022-11-01 20:47:37 +01:00
at_exit( ) {
if [ [ -v UNIT_NAME && -e " /usr/lib/systemd/system/ $UNIT_NAME " ] ] ; then
2022-11-22 05:14:01 +01:00
rm -fvr " /usr/lib/systemd/system/ $UNIT_NAME " " /etc/systemd/system/ $UNIT_NAME .d " "+4"
2022-11-01 20:47:37 +01:00
fi
2022-11-15 21:52:10 +09:00
rm -f /etc/init.d/issue-24990
return 0
2022-11-01 20:47:37 +01:00
}
# Create a simple unit file for testing
# Note: the service file is created under /usr on purpose to test
# the 'revert' verb as well
2022-11-22 05:14:01 +01:00
export UNIT_NAME = " systemctl-test- $RANDOM .service "
2023-12-02 17:15:13 +01:00
export UNIT_NAME2 = " systemctl-test- $RANDOM .service "
2022-11-01 20:47:37 +01:00
cat >" /usr/lib/systemd/system/ $UNIT_NAME " <<\E OF
[ Unit]
Description = systemctl test
[ Service]
ExecStart = sleep infinity
ExecReload = true
# For systemctl clean
CacheDirectory = %n
ConfigurationDirectory = %n
LogsDirectory = %n
RuntimeDirectory = %n
StateDirectory = %n
[ Install]
WantedBy = multi-user.target
EOF
# Configure the preset setting for the unit file
mkdir /run/systemd/system-preset/
echo " disable $UNIT_NAME " >/run/systemd/system-preset/99-systemd-test.preset
2022-11-22 05:14:01 +01:00
EDITOR = 'true' script -ec 'systemctl edit "$UNIT_NAME"' /dev/null
[ ! -e " /etc/systemd/system/ $UNIT_NAME .d/override.conf " ]
2023-02-05 21:41:24 +01:00
printf '%s\n' '[Service]' 'ExecStart=' 'ExecStart=sleep 10d' >"+4"
2022-11-22 05:14:01 +01:00
EDITOR = 'mv' script -ec 'systemctl edit "$UNIT_NAME"' /dev/null
printf '%s\n' '[Service]' 'ExecStart=' 'ExecStart=sleep 10d' | cmp - " /etc/systemd/system/ $UNIT_NAME .d/override.conf "
2023-02-05 21:41:24 +01:00
printf '%b' '[Service]\n' 'ExecStart=\n' 'ExecStart=sleep 10d' >"+4"
2022-11-22 05:14:01 +01:00
EDITOR = 'mv' script -ec 'systemctl edit "$UNIT_NAME"' /dev/null
printf '%s\n' '[Service]' 'ExecStart=' 'ExecStart=sleep 10d' | cmp - " /etc/systemd/system/ $UNIT_NAME .d/override.conf "
2022-11-01 20:47:37 +01:00
2023-12-02 17:15:13 +01:00
systemctl edit " $UNIT_NAME " --stdin --drop-in= override2.conf <<EOF
[ Unit]
Description = spectacular
# this comment should remain
EOF
printf '%s\n' '[Unit]' 'Description=spectacular' '# this comment should remain' | \
cmp - " /etc/systemd/system/ $UNIT_NAME .d/override2.conf "
# Test simultaneous editing of two units and creation of drop-in for a nonexistent unit
systemctl edit " $UNIT_NAME " " $UNIT_NAME2 " --stdin --force --drop-in= override2.conf <<< '[X-Section]'
printf '%s\n' '[X-Section]' | cmp - " /etc/systemd/system/ $UNIT_NAME .d/override2.conf "
printf '%s\n' '[X-Section]' | cmp - " /etc/systemd/system/ $UNIT_NAME2 .d/override2.conf "
2023-02-21 19:30:58 +01:00
# Double free when editing a template unit (#26483)
EDITOR = 'true' script -ec 'systemctl edit user@0' /dev/null
2022-11-01 20:47:37 +01:00
# Argument help
systemctl --state help
systemctl --signal help
systemctl --type help
# list-dependencies
systemctl list-dependencies systemd-journald
systemctl list-dependencies --after systemd-journald
systemctl list-dependencies --before systemd-journald
systemctl list-dependencies --after --reverse systemd-journald
systemctl list-dependencies --before --reverse systemd-journald
systemctl list-dependencies --plain systemd-journald
# list-* verbs
systemctl list-units
systemctl list-units --recursive
systemctl list-units --type= socket
systemctl list-units --type= service,timer
2022-11-02 11:44:00 +01:00
# Compat: --type= allows load states for compatibility reasons
systemctl list-units --type= loaded
systemctl list-units --type= loaded,socket
2022-11-01 20:47:37 +01:00
systemctl list-units --legend= yes -a "systemd-*"
systemctl list-units --state= active
systemctl list-units --with-dependencies systemd-journald.service
systemctl list-units --with-dependencies --after systemd-journald.service
systemctl list-units --with-dependencies --before --reverse systemd-journald.service
systemctl list-sockets
systemctl list-sockets --legend= no -a "*journal*"
systemctl list-sockets --show-types
systemctl list-sockets --state= listening
systemctl list-timers -a -l
systemctl list-jobs
systemctl list-jobs --after
systemctl list-jobs --before
systemctl list-jobs --after --before
systemctl list-jobs "*"
2023-01-13 16:52:29 +08:00
systemctl list-dependencies sysinit.target --type= socket,mount
systemctl list-dependencies multi-user.target --state= active
systemctl list-dependencies sysinit.target --state= mounted --all
2023-02-20 20:14:59 +01:00
systemctl list-paths
systemctl list-paths --legend= no -a "systemd*"
2022-11-01 20:47:37 +01:00
2023-04-06 12:22:36 +02:00
test_list_unit_files( ) {
systemctl list-unit-files " $@ "
systemctl list-unit-files " $@ " "*journal*"
}
test_list_unit_files
test_list_unit_files --root= /
2022-12-13 00:39:31 +08:00
# is-* verbs
# Should return 4 for a missing unit file
assert_rc 4 systemctl --quiet is-active not-found.service
assert_rc 4 systemctl --quiet is-failed not-found.service
assert_rc 4 systemctl --quiet is-enabled not-found.service
# is-active: return 3 when the unit exists but inactive
assert_rc 3 systemctl --quiet is-active " $UNIT_NAME "
# is-enabled: return 1 when the unit exists but disabled
assert_rc 1 systemctl --quiet is-enabled " $UNIT_NAME "
2022-11-01 20:47:37 +01:00
# Basic service management
systemctl start --show-transaction " $UNIT_NAME "
systemctl status -n 5 " $UNIT_NAME "
systemctl is-active " $UNIT_NAME "
systemctl reload -T " $UNIT_NAME "
systemctl restart -T " $UNIT_NAME "
systemctl try-restart --show-transaction " $UNIT_NAME "
systemctl try-reload-or-restart --show-transaction " $UNIT_NAME "
2024-04-30 22:03:00 +02:00
timeout 10 systemctl kill --wait " $UNIT_NAME "
2022-11-01 20:47:37 +01:00
( ! systemctl is-active " $UNIT_NAME " )
systemctl restart " $UNIT_NAME "
systemctl is-active " $UNIT_NAME "
systemctl restart " $UNIT_NAME "
systemctl stop " $UNIT_NAME "
( ! systemctl is-active " $UNIT_NAME " )
2023-10-17 20:47:54 +08:00
assert_eq " $( systemctl is-system-running) " " $( systemctl is-failed) "
2022-11-01 20:47:37 +01:00
# enable/disable/preset
2023-04-06 12:22:36 +02:00
test_enable_disable_preset( ) {
( ! systemctl is-enabled " $@ " " $UNIT_NAME " )
systemctl enable " $@ " " $UNIT_NAME "
systemctl is-enabled " $@ " -l " $UNIT_NAME "
# We created a preset file for this unit above with a "disable" policy
systemctl preset " $@ " " $UNIT_NAME "
( ! systemctl is-enabled " $@ " " $UNIT_NAME " )
systemctl reenable " $@ " " $UNIT_NAME "
systemctl is-enabled " $@ " " $UNIT_NAME "
systemctl preset " $@ " --preset-mode= enable-only " $UNIT_NAME "
systemctl is-enabled " $@ " " $UNIT_NAME "
systemctl preset " $@ " --preset-mode= disable-only " $UNIT_NAME "
( ! systemctl is-enabled " $@ " " $UNIT_NAME " )
systemctl enable " $@ " --runtime " $UNIT_NAME "
[ [ -e " /run/systemd/system/multi-user.target.wants/ $UNIT_NAME " ] ]
systemctl is-enabled " $@ " " $UNIT_NAME "
systemctl disable " $@ " " $UNIT_NAME "
# The unit should be still enabled, as we didn't use the --runtime switch
systemctl is-enabled " $@ " " $UNIT_NAME "
systemctl disable " $@ " --runtime " $UNIT_NAME "
( ! systemctl is-enabled " $@ " " $UNIT_NAME " )
}
test_enable_disable_preset
test_enable_disable_preset --root= /
2022-11-01 20:47:37 +01:00
# mask/unmask/revert
2023-04-06 12:22:36 +02:00
test_mask_unmask_revert( ) {
systemctl disable " $@ " " $UNIT_NAME "
[ [ " $( systemctl is-enabled " $@ " " $UNIT_NAME " ) " = = disabled ] ]
systemctl mask " $@ " " $UNIT_NAME "
[ [ " $( systemctl is-enabled " $@ " " $UNIT_NAME " ) " = = masked ] ]
systemctl unmask " $@ " " $UNIT_NAME "
[ [ " $( systemctl is-enabled " $@ " " $UNIT_NAME " ) " = = disabled ] ]
systemctl mask " $@ " " $UNIT_NAME "
[ [ " $( systemctl is-enabled " $@ " " $UNIT_NAME " ) " = = masked ] ]
systemctl revert " $@ " " $UNIT_NAME "
[ [ " $( systemctl is-enabled " $@ " " $UNIT_NAME " ) " = = disabled ] ]
systemctl mask " $@ " --runtime " $UNIT_NAME "
[ [ " $( systemctl is-enabled " $@ " " $UNIT_NAME " ) " = = masked-runtime ] ]
# This should be a no-op without the --runtime switch
systemctl unmask " $@ " " $UNIT_NAME "
[ [ " $( systemctl is-enabled " $@ " " $UNIT_NAME " ) " = = masked-runtime ] ]
systemctl unmask " $@ " --runtime " $UNIT_NAME "
[ [ " $( systemctl is-enabled " $@ " " $UNIT_NAME " ) " = = disabled ] ]
}
test_mask_unmask_revert
test_mask_unmask_revert --root= /
2022-11-01 20:47:37 +01:00
2024-02-07 22:15:05 +08:00
# disable --now with template unit
cat >/run/systemd/system/test-disable@.service <<EOF
[ Service]
ExecStart = sleep infinity
[ Install]
WantedBy = multi-user.target
EOF
systemctl enable --now test-disable@1.service test-disable@2.service
systemctl is-active test-disable@1.service
systemctl is-active test-disable@2.service
systemctl disable --now test-disable@.service
for u in test-disable@{ 1,2} .service; do
( ! systemctl is-active " $u " )
( ! systemctl is-enabled " $u " )
done
rm /run/systemd/system/test-disable@.service
2022-11-01 20:47:37 +01:00
# add-wants/add-requires
( ! systemctl show -P Wants " $UNIT_NAME " | grep "systemd-journald.service" )
systemctl add-wants " $UNIT_NAME " "systemd-journald.service"
systemctl show -P Wants " $UNIT_NAME " | grep "systemd-journald.service"
( ! systemctl show -P Requires " $UNIT_NAME " | grep "systemd-journald.service" )
systemctl add-requires " $UNIT_NAME " "systemd-journald.service"
systemctl show -P Requires " $UNIT_NAME " | grep "systemd-journald.service"
# set-property
systemctl set-property " $UNIT_NAME " IPAccounting = yes MemoryMax = 1234567
systemctl cat " $UNIT_NAME "
# These properties should be saved to a persistent storage
grep -r "IPAccounting=yes" " /etc/systemd/system.control/ ${ UNIT_NAME } .d/ "
grep -r "MemoryMax=1234567" " /etc/systemd/system.control/ ${ UNIT_NAME } .d "
systemctl revert " $UNIT_NAME "
( ! grep -r "IPAccounting=" " /etc/systemd/system.control/ ${ UNIT_NAME } .d/ " )
( ! grep -r "MemoryMax=" " /etc/systemd/system.control/ ${ UNIT_NAME } .d/ " )
# Same stuff, but with --runtime, which should use /run
systemctl set-property --runtime " $UNIT_NAME " CPUAccounting = no CPUQuota = 10%
systemctl cat " $UNIT_NAME "
grep -r "CPUAccounting=no" " /run/systemd/system.control/ ${ UNIT_NAME } .d/ "
grep -r "CPUQuota=10%" " /run/systemd/system.control/ ${ UNIT_NAME } .d/ "
systemctl revert " $UNIT_NAME "
( ! grep -r "CPUAccounting=" " /run/systemd/system.control/ ${ UNIT_NAME } .d/ " )
( ! grep -r "CPUQuota=" " /run/systemd/system.control/ ${ UNIT_NAME } .d/ " )
# Failed-unit related tests
2022-11-02 11:44:00 +01:00
( ! systemd-run --wait --unit "failed.service" /bin/false)
2022-11-01 20:47:37 +01:00
systemctl is-failed failed.service
systemctl --state= failed | grep failed.service
systemctl --failed | grep failed.service
systemctl reset-failed "fail*.service"
( ! systemctl is-failed failed.service)
# clean
systemctl restart " $UNIT_NAME "
systemctl stop " $UNIT_NAME "
# Check if the directories from *Directory= directives exist
# (except RuntimeDirectory= in /run, which is removed when the unit is stopped)
for path in /var/lib /var/cache /var/log /etc; do
[ [ -e " $path / $UNIT_NAME " ] ]
done
# Run the cleanup
for what in "" configuration state cache logs runtime all; do
systemctl clean ${ what : +--what= " $what " } " $UNIT_NAME "
done
# All respective directories should be removed
for path in /run /var/lib /var/cache /var/log /etc; do
[ [ ! -e " $path / $UNIT_NAME " ] ]
done
# --timestamp
for value in pretty us µs utc us+utc µs+utc; do
systemctl show -P KernelTimestamp --timestamp= " $value "
done
2022-11-02 11:44:00 +01:00
# set-default/get-default
2023-04-06 12:22:36 +02:00
test_get_set_default( ) {
target = " $( systemctl get-default " $@ " ) "
systemctl set-default " $@ " emergency.target
[ [ " $( systemctl get-default " $@ " ) " = = emergency.target ] ]
systemctl set-default " $@ " " $target "
[ [ " $( systemctl get-default " $@ " ) " = = " $target " ] ]
}
test_get_set_default
test_get_set_default --root= /
2022-11-02 11:44:00 +01:00
# show/status
systemctl show --property ""
# Pick a heavily sandboxed unit for the best effect on coverage
systemctl show systemd-logind.service
systemctl status
# Ignore the exit code in this case, as it might try to load non-existing units
systemctl status -a >/dev/null || :
systemctl status -a --state active,running,plugged >/dev/null
systemctl status "systemd-*.timer"
systemctl status "systemd-journald*.socket"
systemctl status "sys-devices-*-ttyS0.device"
systemctl status -- -.mount
2023-01-16 23:46:01 +00:00
systemctl status 1
2022-11-02 11:44:00 +01:00
# --marked
systemctl restart " $UNIT_NAME "
systemctl set-property " $UNIT_NAME " Markers = needs-restart
systemctl show -P Markers " $UNIT_NAME " | grep needs-restart
systemctl reload-or-restart --marked
( ! systemctl show -P Markers " $UNIT_NAME " | grep needs-restart)
# --dry-run with destructive verbs
# kexec is skipped intentionally, as it requires a bit more involved setup
VERBS = (
default
emergency
exit
halt
hibernate
hybrid-sleep
poweroff
reboot
rescue
suspend
suspend-then-hibernate
)
for verb in " ${ VERBS [@] } " ; do
systemctl --dry-run " $verb "
if [ [ " $verb " = ~ ( halt| poweroff| reboot) ] ] ; then
systemctl --dry-run --message "Hello world" " $verb "
systemctl --dry-run --no-wall " $verb "
systemctl --dry-run -f " $verb "
systemctl --dry-run -ff " $verb "
fi
done
2022-11-01 20:47:37 +01:00
# Aux verbs & assorted checks
systemctl is-active "*-journald.service"
2023-12-21 15:32:15 +00:00
systemctl cat "*udevd*"
2022-11-01 20:47:37 +01:00
systemctl cat " $UNIT_NAME "
systemctl help " $UNIT_NAME "
2022-11-02 11:44:00 +01:00
systemctl service-watchdogs
systemctl service-watchdogs " $( systemctl service-watchdogs) "
2022-11-01 20:47:37 +01:00
# show/set-environment
2018-11-26 21:16:27 +01:00
# Make sure PATH is set
systemctl show-environment | grep -q '^PATH='
# Let's add an entry and override a built-in one
systemctl set-environment PATH = /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/testaddition FOO = BAR
# Check that both are set
systemctl show-environment | grep -q '^PATH=.*testaddition$'
systemctl show-environment | grep -q '^FOO=BAR$'
systemctl daemon-reload
# Check again after the reload
systemctl show-environment | grep -q '^PATH=.*testaddition$'
systemctl show-environment | grep -q '^FOO=BAR$'
2021-12-01 15:06:29 +01:00
# Check that JSON output is supported
systemctl show-environment --output= json | grep -q '^{.*"FOO":"BAR".*}$'
2018-11-26 21:16:27 +01:00
# Drop both
systemctl unset-environment FOO PATH
# Check that one is gone and the other reverted to the built-in
2021-04-08 01:27:33 +02:00
systemctl show-environment | grep '^FOO=$' && exit 1
systemctl show-environment | grep '^PATH=.*testaddition$' && exit 1
2018-11-26 21:16:27 +01:00
systemctl show-environment | grep -q '^PATH='
2022-11-01 20:47:37 +01:00
# Check import-environment
export IMPORT_THIS = hello
export IMPORT_THIS_TOO = world
systemctl import-environment IMPORT_THIS IMPORT_THIS_TOO
systemctl show-environment | grep " ^IMPORT_THIS= $IMPORT_THIS "
systemctl show-environment | grep " ^IMPORT_THIS_TOO= $IMPORT_THIS_TOO "
systemctl unset-environment IMPORT_THIS IMPORT_THIS_TOO
( ! systemctl show-environment | grep "^IMPORT_THIS=" )
( ! systemctl show-environment | grep "^IMPORT_THIS_TOO=" )
2018-11-26 21:16:27 +01:00
2022-11-15 21:52:10 +09:00
# test for sysv-generator (issue #24990)
if [ [ -x /usr/lib/systemd/system-generators/systemd-sysv-generator ] ] ; then
2023-01-13 20:10:42 +01:00
# This is configurable via -Dsysvinit-path=, but we can't get the value
# at runtime, so let's just support the two most common paths for now.
[ [ -d /etc/rc.d/init.d ] ] && SYSVINIT_PATH = "/etc/rc.d/init.d" || SYSVINIT_PATH = "/etc/init.d"
2024-04-24 14:44:27 +01:00
# OpenSUSE leaves sysvinit-path enabled, which means systemd-sysv-generator is built
# but may not create the directory if there's no services that use it.
mkdir -p " $SYSVINIT_PATH "
2022-11-15 21:52:10 +09:00
# invalid dependency
2023-01-13 20:10:42 +01:00
cat >" ${ SYSVINIT_PATH : ? } /issue-24990 " <<\E OF
2022-11-15 21:52:10 +09:00
#!/bin/bash
### BEGIN INIT INFO
# Provides:test1 test2
# Required-Start:test1 $remote_fs $network
# Required-Stop:test1 $remote_fs $network
# Description:Test
# Short-Description: Test
### END INIT INFO
case " $1 " in
start)
echo "Starting issue-24990.service"
sleep 1000 &
; ;
stop)
echo "Stopping issue-24990.service"
sleep 10 &
; ;
*)
echo "Usage: service test {start|stop|restart|status}"
; ;
esac
EOF
2023-01-13 20:10:42 +01:00
chmod +x " $SYSVINIT_PATH /issue-24990 "
2022-11-15 21:52:10 +09:00
systemctl daemon-reload
[ [ -L /run/systemd/generator.late/test1.service ] ]
[ [ -L /run/systemd/generator.late/test2.service ] ]
assert_eq " $( readlink -f /run/systemd/generator.late/test1.service) " "/run/systemd/generator.late/issue-24990.service"
assert_eq " $( readlink -f /run/systemd/generator.late/test2.service) " "/run/systemd/generator.late/issue-24990.service"
output = $( systemctl cat issue-24990)
2023-01-13 20:10:42 +01:00
assert_in " SourcePath= $SYSVINIT_PATH /issue-24990 " " $output "
2022-11-15 21:52:10 +09:00
assert_in "Description=LSB: Test" " $output "
assert_in "After=test1.service" " $output "
assert_in "After=remote-fs.target" " $output "
assert_in "After=network-online.target" " $output "
assert_in "Wants=network-online.target" " $output "
2023-01-13 20:10:42 +01:00
assert_in " ExecStart= $SYSVINIT_PATH /issue-24990 start " " $output "
assert_in " ExecStop= $SYSVINIT_PATH /issue-24990 stop " " $output "
2022-11-15 21:52:10 +09:00
systemctl status issue-24990 || :
systemctl show issue-24990
assert_not_in "issue-24990.service" " $( systemctl show --property= After --value) "
assert_not_in "issue-24990.service" " $( systemctl show --property= Before --value) "
if ! systemctl is-active network-online.target; then
systemctl start network-online.target
fi
systemctl restart issue-24990
systemctl stop issue-24990
# valid dependency
2023-01-13 20:10:42 +01:00
cat >" $SYSVINIT_PATH /issue-24990 " <<\E OF
2022-11-15 21:52:10 +09:00
#!/bin/bash
### BEGIN INIT INFO
# Provides:test1 test2
# Required-Start:$remote_fs
# Required-Stop:$remote_fs
# Description:Test
# Short-Description: Test
### END INIT INFO
case " $1 " in
start)
echo "Starting issue-24990.service"
sleep 1000 &
; ;
stop)
echo "Stopping issue-24990.service"
sleep 10 &
; ;
*)
echo "Usage: service test {start|stop|restart|status}"
; ;
esac
EOF
2018-11-26 21:16:27 +01:00
2023-01-13 20:10:42 +01:00
chmod +x " $SYSVINIT_PATH /issue-24990 "
2022-11-15 21:52:10 +09:00
systemctl daemon-reload
[ [ -L /run/systemd/generator.late/test1.service ] ]
[ [ -L /run/systemd/generator.late/test2.service ] ]
assert_eq " $( readlink -f /run/systemd/generator.late/test1.service) " "/run/systemd/generator.late/issue-24990.service"
assert_eq " $( readlink -f /run/systemd/generator.late/test2.service) " "/run/systemd/generator.late/issue-24990.service"
output = $( systemctl cat issue-24990)
2023-01-13 20:10:42 +01:00
assert_in " SourcePath= $SYSVINIT_PATH /issue-24990 " " $output "
2022-11-15 21:52:10 +09:00
assert_in "Description=LSB: Test" " $output "
assert_in "After=remote-fs.target" " $output "
2023-01-13 20:10:42 +01:00
assert_in " ExecStart= $SYSVINIT_PATH /issue-24990 start " " $output "
assert_in " ExecStop= $SYSVINIT_PATH /issue-24990 stop " " $output "
2022-11-15 21:52:10 +09:00
systemctl status issue-24990 || :
systemctl show issue-24990
assert_not_in "issue-24990.service" " $( systemctl show --property= After --value) "
assert_not_in "issue-24990.service" " $( systemctl show --property= Before --value) "
systemctl restart issue-24990
systemctl stop issue-24990
fi
2018-11-26 21:16:27 +01:00
2023-02-21 19:15:13 +01:00
# %J in WantedBy= causes ABRT (#26467)
cat >/run/systemd/system/test-WantedBy.service <<EOF
[ Service]
ExecStart = true
[ Install]
WantedBy = user-%i@%J.service
EOF
systemctl daemon-reload
systemctl enable --now test-WantedBy.service || :
systemctl daemon-reload
2022-11-15 21:52:10 +09:00
touch /testok