You are not logged in.
I have a Python script that, when started on the command line, will respond to SIGUSR1 with a printed line. When I start this script using a systemd unit and send that signal, I expect to find this line when tailing journalctl, but it is not there.
I start the script in the unit file like this:
ExecStart=/home/myuser/server/venv/bin/python server.py config.ini
User=myuser
Group=mygroupI send the signal using the same user.
systemctl show -p MainPID server.servicegives me the same PID as
pgrep -f "python server.py"Does anyone know why the signal is not reaching my script, only when using systemd?
Last edited by diederick76 (2025-03-19 17:08:54)
Offline
I'm not aware of any signal blocking capabilities in systemd, and it's unlikely you've enabled any by accident. Still, maybe share the full service file and the output of
systemctl show server.serviceFWIW, sshd responds to sighup as expected:
# killall -HUP sshd
# systemctl status sshd
[...]
Mar 19 18:34:15 sakura sshd[917]: Received SIGHUP; restarting.
Mar 19 18:34:15 sakura sshd[917]: Server listening on 0.0.0.0 port 22.
Mar 19 18:34:15 sakura sshd[917]: Server listening on :: port 22.Sakura:-
Mobo: MSI MAG X570S TORPEDO MAX // Processor: AMD Ryzen 9 5950X @4.9GHz // GFX: AMD Radeon RX 5700 XT // RAM: 32GB (4x 8GB) Corsair DDR4 (@ 3000MHz) // Storage: 1x 3TB HDD, 6x 1TB SSD, 2x 120GB SSD, 1x 275GB M2 SSD
Making lemonade from lemons since 2015.
Offline
I'm guessing here, but systemd utilizes process isolation, so I'm not surprised signaling via `kill` doesn't work. However, it does sound like a possible X-Y problem: what are you trying to achieve? Are you trying to communicate with the service/daemon? Because there are other ways to accomplish that.
Offline
I'm not aware of any signal blocking capabilities in systemd, and it's unlikely you've enabled any by accident. Still, maybe share the full service file and the output of
systemctl show server.service
[Unit]
Description=Static blogging platform
[Service]
WorkingDirectory=/home/myuser/server/
ExecStart=/home/myuser/server/venv/bin/python server.py config.ini
User=myuser
Group=mygroup
[Install]
WantedBy=multi-user.targetType=simple
ExitType=main
Restart=no
RestartMode=normal
NotifyAccess=none
RestartUSec=100ms
RestartSteps=0
RestartMaxDelayUSec=infinity
RestartUSecNext=100ms
TimeoutStartUSec=1min 30s
TimeoutStopUSec=1min 30s
TimeoutAbortUSec=1min 30s
TimeoutStartFailureMode=terminate
TimeoutStopFailureMode=terminate
RuntimeMaxUSec=infinity
RuntimeRandomizedExtraUSec=0
WatchdogUSec=0
WatchdogTimestampMonotonic=0
RootDirectoryStartOnly=no
RemainAfterExit=no
GuessMainPID=yes
MainPID=16793
ControlPID=0
FileDescriptorStoreMax=0
NFileDescriptorStore=0
FileDescriptorStorePreserve=restart
StatusErrno=0
Result=success
ReloadResult=success
CleanResult=success
LiveMountResult=success
UID=1002
GID=1002
NRestarts=0
OOMPolicy=stop
ReloadSignal=1
ExecMainStartTimestamp=Wed 2025-03-19 17:22:33 CET
ExecMainStartTimestampMonotonic=513119614845
ExecMainExitTimestampMonotonic=0
ExecMainHandoffTimestamp=Wed 2025-03-19 17:22:33 CET
ExecMainHandoffTimestampMonotonic=513119720844
ExecMainPID=16793
ExecMainCode=0
ExecMainStatus=0
ExecStart={ path=/home/myuser/server/venv/bin/python ; argv[]=/home/myuser/server/venv/bin/p>
ExecStartEx={ path=/home/myuser/server/venv/bin/python ; argv[]=/home/myuser/server/venv/bin>
Slice=system.slice
ControlGroup=/system.slice/server.service
ControlGroupId=4294976043
MemoryCurrent=[not set]
MemoryPeak=[not set]
MemorySwapCurrent=[not set]
MemorySwapPeak=[not set]
MemoryZSwapCurrent=[not set]
MemoryAvailable=3861016576
EffectiveMemoryMax=4019134464
EffectiveMemoryHigh=4019134464
CPUUsageNSec=23914233000
TasksCurrent=3
EffectiveTasksMax=4915
IPIngressBytes=[no data]
IPIngressPackets=[no data]
IPEgressBytes=[no data]
IPEgressPackets=[no data]
IOReadBytes=[not set]
IOReadOperations=[not set]
IOWriteBytes=[not set]
IOWriteOperations=[not set]
Delegate=no
CPUAccounting=yes
CPUWeight=[not set]
StartupCPUWeight=[not set]
CPUShares=[not set]
StartupCPUShares=[not set]
CPUQuotaPerSecUSec=infinity
CPUQuotaPeriodUSec=infinity
IOAccounting=no
IOWeight=[not set]
StartupIOWeight=[not set]
BlockIOAccounting=no
BlockIOWeight=[not set]
StartupBlockIOWeight=[not set]
MemoryAccounting=yes
DefaultMemoryLow=0
DefaultStartupMemoryLow=0
DefaultMemoryMin=0
MemoryMin=0
MemoryLow=0
StartupMemoryLow=0
MemoryHigh=infinity
StartupMemoryHigh=infinity
MemoryMax=infinity
StartupMemoryMax=infinity
MemorySwapMax=infinity
StartupMemorySwapMax=infinity
MemoryZSwapMax=infinity
StartupMemoryZSwapMax=infinity
MemoryZSwapWriteback=yes
MemoryLimit=infinity
DevicePolicy=auto
TasksAccounting=yes
TasksMax=4915
IPAccounting=no
ManagedOOMSwap=auto
ManagedOOMMemoryPressure=auto
ManagedOOMMemoryPressureLimit=0
ManagedOOMMemoryPressureDurationUSec=[not set]
ManagedOOMPreference=none
MemoryPressureWatch=auto
MemoryPressureThresholdUSec=200ms
CoredumpReceive=no
UMask=0022
LimitCPU=infinity
LimitCPUSoft=infinity
LimitFSIZE=infinity
LimitFSIZESoft=infinity
LimitDATA=infinity
LimitDATASoft=infinity
LimitSTACK=infinity
LimitSTACKSoft=8388608
LimitCORE=infinity
LimitCORESoft=infinity
LimitRSS=infinity
LimitRSSSoft=infinity
LimitNOFILE=524288
LimitNOFILESoft=1024
LimitAS=infinity
LimitASSoft=infinity
LimitNPROC=26490
LimitNPROCSoft=26490
LimitMEMLOCK=8388608
LimitMEMLOCKSoft=8388608
LimitLOCKS=infinity
LimitLOCKSSoft=infinity
LimitSIGPENDING=26490
LimitSIGPENDINGSoft=26490
LimitMSGQUEUE=819200
LimitMSGQUEUESoft=819200
LimitNICE=0
LimitNICESoft=0
LimitRTPRIO=0
LimitRTPRIOSoft=0
LimitRTTIME=infinity
LimitRTTIMESoft=infinity
WorkingDirectory=/home/myuser/server
RootEphemeral=no
OOMScoreAdjust=0
CoredumpFilter=0x33
Nice=0
IOSchedulingClass=2
IOSchedulingPriority=4
CPUSchedulingPolicy=0
CPUSchedulingPriority=0
CPUAffinityFromNUMA=no
NUMAPolicy=n/a
TimerSlackNSec=50000
CPUSchedulingResetOnFork=no
NonBlocking=no
StandardInput=null
StandardOutput=journal
StandardError=inherit
TTYReset=no
TTYVHangup=no
TTYVTDisallocate=no
SyslogPriority=30
SyslogLevelPrefix=yes
SyslogLevel=6
SyslogFacility=3
LogLevelMax=-1
LogRateLimitIntervalUSec=0
LogRateLimitBurst=0
SecureBits=0
CapabilityBoundingSet=cap_chown cap_dac_override cap_dac_read_search cap_fowner cap_fsetid cap>
User=myuser
Group=mygroup
DynamicUser=no
SetLoginEnvironment=yes
RemoveIPC=no
PrivateTmp=no
PrivateTmpEx=no
PrivateDevices=no
ProtectClock=no
ProtectKernelTunables=no
ProtectKernelModules=no
ProtectKernelLogs=no
ProtectControlGroups=no
ProtectControlGroupsEx=no
PrivateNetwork=no
PrivateUsers=no
PrivateUsersEx=no
PrivateMounts=no
PrivateIPC=no
PrivatePIDs=no
ProtectHome=no
ProtectSystem=no
SameProcessGroup=no
UtmpMode=init
IgnoreSIGPIPE=yes
NoNewPrivileges=no
SystemCallErrorNumber=2147483646
LockPersonality=no
RuntimeDirectoryPreserve=no
RuntimeDirectoryMode=0755
StateDirectoryMode=0755
CacheDirectoryMode=0755
LogsDirectoryMode=0755
ConfigurationDirectoryMode=0755
TimeoutCleanUSec=infinity
MemoryDenyWriteExecute=no
RestrictRealtime=no
RestrictSUIDSGID=no
RestrictNamespaces=no
MountAPIVFS=no
BindLogSockets=no
KeyringMode=private
ProtectProc=default
ProcSubset=all
ProtectHostname=no
MemoryKSM=no
RootImagePolicy=root=verity+signed+encrypted+unprotected+absent:usr=verity+signed+encrypted+un>
MountImagePolicy=root=verity+signed+encrypted+unprotected+absent:usr=verity+signed+encrypted+u>
ExtensionImagePolicy=root=verity+signed+encrypted+unprotected+absent:usr=verity+signed+encrypt>
KillMode=control-group
KillSignal=15
RestartKillSignal=15
FinalKillSignal=9
SendSIGKILL=yes
SendSIGHUP=no
WatchdogSignal=6
Id=server.service
Names=server.service
Requires=sysinit.target system.slice
WantedBy=multi-user.target
Conflicts=shutdown.target
Before=multi-user.target shutdown.target
After=-.mount sysinit.target basic.target system.slice systemd-journald.socket
RequiresMountsFor=/home/myuser/server
Description=server static blogging platform
LoadState=loaded
ActiveState=active
FreezerState=running
SubState=running
FragmentPath=/etc/systemd/system/server.service
UnitFileState=enabled
UnitFilePreset=disabled
StateChangeTimestamp=Wed 2025-03-19 17:22:33 CET
StateChangeTimestampMonotonic=513119616414
InactiveExitTimestamp=Wed 2025-03-19 17:22:33 CET
InactiveExitTimestampMonotonic=513119616414
ActiveEnterTimestamp=Wed 2025-03-19 17:22:33 CET
ActiveEnterTimestampMonotonic=513119616414
ActiveExitTimestamp=Wed 2025-03-19 17:21:59 CET
ActiveExitTimestampMonotonic=513085704577
InactiveEnterTimestamp=Wed 2025-03-19 17:21:59 CET
InactiveEnterTimestampMonotonic=513085704577
CanStart=yes
CanStop=yes
CanReload=no
CanIsolate=no
CanFreeze=yes
CanLiveMount=no
StopWhenUnneeded=no
RefuseManualStart=no
RefuseManualStop=no
AllowIsolate=no
DefaultDependencies=yes
SurviveFinalKillSignal=no
OnSuccessJobMode=fail
OnFailureJobMode=replace
IgnoreOnIsolate=no
NeedDaemonReload=no
JobTimeoutUSec=infinity
JobRunningTimeoutUSec=infinity
JobTimeoutAction=none
ConditionResult=yes
AssertResult=yes
ConditionTimestamp=Wed 2025-03-19 17:22:33 CET
ConditionTimestampMonotonic=513119612859
AssertTimestamp=Wed 2025-03-19 17:22:33 CET
AssertTimestampMonotonic=513119612866
Transient=no
Perpetual=no
StartLimitIntervalUSec=10s
StartLimitBurst=5
StartLimitAction=none
FailureAction=none
SuccessAction=none
InvocationID=cd1ffd6071224fc2b9a3331c2d9cd1c9
CollectMode=inactive
DebugInvocation=noOffline
I'm guessing here, but systemd utilizes process isolation, so I'm not surprised signaling via `kill` doesn't work. However, it does sound like a possible X-Y problem: what are you trying to achieve? Are you trying to communicate with the service/daemon? Because there are other ways to accomplish that.
Yes, I have to signal the script to execute a function. What other ways to communicate with a service/daemon do you mean?
Offline
I expect to find this line when tailing journalctl, but it is not there.
Python's print() is buffered on non-tty stdout. E.g. redirect stdout of your script in shell to a pipe:
$ /home/myuser/server/venv/bin/python server.py config.ini | catand send SIGUSR1.
To make it unbuffered you can run python with -u option
ExecStart=/home/myuser/server/venv/bin/python -u server.py config.inior set PYTHONUNBUFFERED variable:
[Service]
Environment=PYTHONUNBUFFERED=1
...or add flush=True to print():
def handler(signum, frame):
signame = signal.Signals(signum).name
print(f'Got {signame} ({signum})', flush=True)What other ways to communicate with a service/daemon do you mean?
Modern way is D-Bus. "Classic" named pipes or sockets are also good.
Last edited by dimich (2025-03-19 20:25:52)
Offline
Thanks, I'll look into that.
Offline
Thanks, I'll look into that.
I mean, your script receives SIGUSR1 but print() output doesn't appear in journal instantly because of bufferization.
Offline
diederick76 wrote:Thanks, I'll look into that.
I mean, your script receives SIGUSR1 but print() output doesn't appear in journal instantly because of bufferization.
I haven't looked into why, but all other print statements in my python scripts end up in the journal. There was nothing special I did for that, which is why I regard that as a test.
Offline