Hi everyone!
When I run asterisk from systemctl, scripts using applications are not executed for example:
[Unit]
Description=Asterisk PBX and telephony daemon.
After=network.target
#include these if asterisk need to bind to a specific IP (other than 0.0.0.0)
#Wants=network-online.target
#After=network-online.target network.target
[Service]
Type=simple
Environment=HOME=/var/lib/asterisk
#if systemd do not provide hostname and you need to use ${ENV(HOSTNAME)}
#Environment=HOSTNAME=%H
WorkingDirectory=/var/lib/asterisk
User=asterisk
Group=asterisk
ExecStart=/usr/sbin/asterisk -mqfg -C /etc/asterisk/asterisk.conf
ExecReload=/usr/sbin/asterisk -rx 'core reload'
#if /var/run is a tmpfs, this will create /var/run/asterisk on start
#RuntimeDirectory=asterisk
#Nice=0
#UMask=0002
LimitCORE=infinity
#LimitNOFILE=
Restart=always
RestartSec=4
# Prevent duplication of logs with color codes to /var/log/messages
StandardOutput=null
PrivateTmp=true
[Install]
WantedBy=multi-user.target
SEND_CALL=/var/lib/asterisk/scripts/send_record.py
exten => 111,n,System(${SEND_CALL})
or
exten => 111,n,MixMonitor(${INRECPATH}${RECFILENAME}.wav,,/var/lib/asterisk/scripts/send_record.py)
it runs from asterisk
asterisk 326055 5.4 1.9 1200664 77744 ? Ssl 12:17 1:17 /usr/sbin/asterisk -mqfg -C /etc/asterisk/asterisk.conf
asterisk.conf
[directories](!)
astcachedir => /tmp
astetcdir => /etc/asterisk
astmoddir => /usr/lib/asterisk/modules
astvarlibdir => /var/lib/asterisk
astdbdir => /var/lib/asterisk
astkeydir => /var/lib/asterisk
astdatadir => /var/lib/asterisk
astagidir => /var/lib/asterisk/agi-bin
astspooldir => /var/spool/asterisk
astrundir => /var/run/asterisk
astlogdir => /var/log/asterisk
astsbindir => /usr/sbin
but in case you run it bash without changing dialplan like this:
root@asterisk:/home/user# su - asterisk
asterisk -vvvgc
it works as expected
Permission:
-rwxrwxrwx 1 asterisk asterisk 635 Jul 15 23:43 /var/lib/asterisk/scripts/send_record.py
This permission is very bad practice. You should give it no more than rwxr_xr_x, and it is best practice for non-set user scripts to be owned by root, with group root, so that they cannot be changed by a compromised application running on the working account.
As to the original problem, I suspect you are using incomplete file names and sysctl isn’t setting up a complete environment, in particular PATH.
Thanks for the answer
Changed privileges
-rwxr-xr-x 1 root root 647 Jul 16 16:18 send_record.py
Environment=PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
Can you please explain in more detail about the names?
If you have a #! line which doesn’t have a full path name, you will need the correct PATH variable. Similarly for other file names that are looked up in a list of directories from the environment.
Also, had did you find out the PATH in Asterisk environment?
What do you get from the shell command:
cat /proc/<insert the PID of the main asterisk process here>/environ
I don’t have asterisk on this machine, so I’ll use BOINC as a proxy:
root@dhcppc4:~# ps -e | grep boinc
712 ? 00:03:45 boinc
root@dhcppc4:~# cat /proc/712/environ
LANG=en_GB.UTF-8LC_MEASUREMENT=en_GB.utf8LC_MONETARY=en_GB.utf8LC_NUMERIC=en_GB.utf8LC_PAPER=en_GB.utf8LC_TIME=en_GB.utf8PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/binHOME=/var/lib/boinc-clientLOGNAME=boincUSER=boincINVOCATION_ID=5c2020ea4e3b49ea9cb54300d1f68b19JOURNAL_STREAM=9:22150root@dhcppc4:~#
(There are NULs in this output.)
Thanks for reply!
Script shebang
#!/usr/bin/env python3
cat /proc/ASTERISK_PID/environ
LANG=en_US.UTF-8PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/binHOME=/var/lib/asteriskLOGNAME=asteriskUSER=asteriskSHELL=/bin/bashINVOCATION_ID=ea0b053f90da42ea8f51e8f43f5de78froot@asterisk
When I enable full debug no any errors just message that script executed
Does it make any assumptions about standard input/output/error?
(In any case, you should probably redirect standard error to a file, for debugging.)
“it” refers to your script.
This is a simple script there can be no errors. I mean no dynamic variables
But you can still get errors from the shell, from /usr/bin/env, or from the python interpreter.
I made a simple script, specifically making an error to check whether the error will be written to the file
wwrite is mistake
#!/usr/bin/env python3
logf = open('/var/lib/asterisk/my.log', 'w+')
try:
with open('/tmp/simple.txt', 'w+') as f:
f.wwrite('EXEC FROM ASTER')
except Exception as e:
logf.write(str(e))
logf.close()
asterisk output CLI
== MixMonitor close filestream (mixed)
== Executing [/var/lib/asterisk/scripts/send_record.py]
== End MixMonitor Recording SIP/protei-000028fc
If you execute this file on behalf of asterisk in bash
, the file is created, but the application (MixMonitor or System) not.
That’s basically not surprising, given what you’ve already said, and the failure is probably happening before any user code is executed, so the log file can’t be used.
How do you think it is better to catch the error?
== Executing [/var/lib/asterisk/scripts/send_record.py 2> /tmp/err.log]
/tmp/err.log not created
finally found the problem:
root@asterisk:/var/lib/asterisk# cat my.log
[Errno 2] No such file or directory: '/tmp/t.wav'
root@asterisk:/var/lib/asterisk# ls /tmp/t.wav
/tmp/t.wav
it can not find file @_@ which exist
The problem was always there, I changed the rights to the audio recording file and everything worked.
I know that is basic but if someone will have problem using python script
use try, expect
try:
YOUR CODE HERE
except Exception as e:
logf = open('/var/lib/asterisk/my.log', 'w+')
logf.write(str(e))
logf.close()
then read my.log file
ALWAYS CHECK PERMISSION!
Thanks you @david551
You pointed in the right direction.
Using syslog is preferable to private log files for several reasons.