I have a bourne shell script (at my NAS) that handles the ffmpeg recording of all my ipcams. For switching the record time (etc) of some cams, that sh script should be restarted daily at 2 different hours (07:00am and 10:00pm), which is configured in the bash script and works well.
To start the sh script, I make use of systemd with the following .service file:
[Unit]
Description=record ipcams
After=tmp.mount network.target
Requires=network.target
RequiresMountsFor=/media/USB2
[Service]
Type=forking
PIDFile=/var/run/cams_record.pid
ExecStart=/bin/bash -c '/media/USB2/movie/cams/cams_record.sh'
TimeoutStopSec=1
Restart=always
[Install]
WantedBy=multi-user.target
So far so good. Now what I actually want, is to restart that script file daily at 07:00am and 10:00pm (or restart the previous mentioned .service at those two times) thus I thought to make use of a systemd timer. I created such a timer for 07:00 am (with the option: OnCalender=07:00)
Question is: having a (permanently running) service, how do I restart that service (and thus the script file) at 07:00am and 22:00pm. I can of course make use of 2 systemd timers (1 for 07:00am and 1 for 10:00pm), but is there a possibility to combine these; i.e. using 1 systemd timer for both times.
With a templates timers, you can do something like this
cat test#.timer
[Unit]
Description=test
[Timer]
OnCalendar=%i:00
Unit=test.service
[Install]
WantedBy=timers.target
Then :
systemctl daemon-reload
and
systemctl start test#07.service
systemctl start test#22.service
Source : https://fedoramagazine.org/systemd-template-unit-files/ and https://jason.the-graham.com/2013/03/06/how-to-use-systemd-timers/
You can use several OnCalendar in one timer, see documentation https://www.freedesktop.org/software/systemd/man/systemd.timer.html#OnCalendar=
[Unit]
Description=test
[Timer]
OnCalendar=07:00
OnCalendar=10:00
Unit=test.service
[Install]
WantedBy=timers.target
Related
I am trying to do a simple kernel verifying systemd service.
Service is:
[Unit]
Description= It checks kernel version
[Service]
ExecStart=/home/handle-kernel-version.sh $EXPECTED_KERNEL $(uname -r)
StandardOutput=journal+console
EnvironmentFile=/home/input_kernel.txt
Type=oneshot
[Install]
WantedBy=multi-user.target
Problem is, the second argument is passed as $(uname instead of the actual kernel version. I suppose it is due to the systemd handling of escape character and I can surely bypass this issue by adding the uname line in the bash script itself, but I would like to know the solution for the oneline method nevertheless.
I have a script which does things with screen brightness, works fine that's cool and now I want to make it run after wake up from suspend.
So I tried using systemd, I have a file under /etc/systemd/system/myscript.service which is as follows:
[Unit]
Description=Run myscript after wakeup
After=suspend.target hibernate.target hybrid-sleep.target suspend-then-hibernate.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/myscript
User=me
#Environment=DISPLAY=:0
[Install]
WantedBy=suspend.target hibernate.target hybrid-sleep.target suspend-then-hibernate.target
Note: User is set because the myscript needs HOME variable.
After I run sudo systemctl enable myscript and try suspend/wakeup, myscript is not run and journalctl -u myscript.service outputs the following message:
Jan 25 13:42:53 mymachine myscript[24489]: Can't open display
Jan 25 13:42:53 mymachine systemd[1]: myscript.service: Succeeded.
Jan 25 13:42:53 mymachine systemd[1]: Finished Run myscript after wakeup.
If I uncomment the line #Environment=DISPLAY=:0 in myscript.service the error is "Can't open display :0"
Any help would be great :^)
This worked on my Arch system. I tested a script in that location with xbacklight going up and down by 75% a few times after a resume from hibernate or suspend (systemctl hibernate / suspend).
I can only think that you do not have the DISPLAY=:0 in your environment (verify with env) for the user you are running the script as.
I was having a similar problem. Fixed it by adding the following to my systemd service:
Environment="DISPLAY=<DISP>"
Environment="XAUTHORITY=/path/to/xauthority"
Replace <DISP> with the value of your $DISPLAY variable, this is usually :0.
I am tweaking snmpd systemd service and I want to execute a script in ExecStartPost. This will be an infinite loop script.
This script is an implementation of agentx ..
I have tried running in a normal manner with and without & , but after sometime the systemd service is timing out..
it is timing out expecting a exit status from the script is what is believe.
Is there any way to run the script in background without the systemd snmp service timing out ?
[Unit]
Description=Simple Network Management Protocol (SNMP) Daemon.
After=syslog.target network.target
[Service]
Type=notify
Environment=OPTIONS="-LS0-6d"
EnvironmentFile=-/etc/sysconfig/snmpd
ExecStart=/usr/sbin/snmpd $OPTIONS -f
ExecStartPost=/usr/bin/python /usr/local/bin/pyagent.py
ExecReload=/bin/kill -HUP $MAINPID
[Install]
WantedBy=multi-user.target
From reading the documentation, I believe you want to keep your & but add - prefix to skip result checking:
ExecStartPost=-/usr/bin/python /usr/local/bin/pyagent.py &
i want to multiple command in myapp.service file in systemd
[Unit]
Description=to serve myapp
[Service]
User=ubuntu
WorkingDirectory=/home/ubuntu/myapp
ExecStart=/home/ubuntu/.local/bin/pserve production.ini http_port=5000
ExecStart=/home/ubuntu/.local/bin/pserve production.ini http_port=5001
Restart=always
[Install]
WantedBy=multi-user.target
it throws error saying invalid argument.
i want to run two commands
pserve production.ini http_port=5000
pserve production.ini http_port=5001
How do i do that??
You can start multiple background processes from one systemd unit, but systemd will not be able to track them for you and do all the nice things that it does to support a daemon, such as send signals to it on various system events or auto-restart it when needed.
If you must have it as a single unit, then you can do one of the following (in my order of preference):
make the two servers separate units (note you may be able to use the same config file for both, so they are two 'instances' of the same service - which makes sense, they run the same server). You will have two entries in the list of running services when you run 'systemctl'.
make that unit a one-shot (runs a program that exits and is not monitored and restarted). Make the one-shot command start both servers in background, e.g.,
sh -c " { pserve production.ini http_port=5000 & pserve production.ini http_port=5001 & } </dev/null >/dev/null >&1"
make a script that launches both daemons and watches for them, restarting them if needed and kills them when it is killed itself. Then you make that script the 'daemon' that systemd runs. Not really worth it, IMO - because you're doing much of the work that systemd itself is best suited to do. Of course you can spin a new copy of systemd that is configured to run just those two servers (and make that systemd as your 'one-service-for-two-commands' unit), but that seems an overkill.
I'm running embedded linux on an Altera FPGA. It uses SystemD to run startup, and I have a script in the "multi-user.target.wants" section that runs my application.
When it runs from startup my code runs slower than when I run the identical script from an ssh shell.
I have checked that paths are the same, that permissions are correct on the scripts, that full paths are used in the scripts. Using 'top' I can see that priorities are set the same for the various threads started, yet somehow performance is completely different between the two ways of starting.
The script in full is:
#!/bin/sh
sleep 5s
mount /dev/mmcblk0p5 /home/root/linux
cd /home/root/linux/mem_driver
./memdev_load
cd /home/root/linux/gpio_driver
insmod ./gpiodev.ko
mknod /dev/gpiodev c 249 0
sleep 5s
cd /home/root/src/control
mysqld_safe &
up=0
while [ $up -ne 2 ]
do
up=$(pgrep mysql | wc -l);
echo $up
done
sleep 3s
cd /home/root/studio_web/myapp
npm start &
sleep 1s
cd /home/root/src/control
#sleep 1s
./control > /home/root/linux/output.log
various sleep commands have been inserted to try and make sure things start up in the right order.
Any help in diagnosing why this behaves differently would be greatly appreciated.
Is that the only shell script you are using? or do you have a systemd service file that executes that single shell script?
Using sleep is ineffective here. You should separate them into separate shell scripts and then use systemd to ensure that the shell scripts are run in order.
For example, we want to mount the directory first, because if this fails then nothing following will be successful. So we create a systemd mount service:
# home-root-linux.mount
[Unit]
Description=Mount /home/root/linux
Before=gpiodev.service
[Mount]
What=/dev/mmcblk0p5
Where=/home/root/linux
Options=defaults
[Install]
WantedBy=multi-user.target
Then we can create another systemd service which depends on the mount above before executing the three parts of the shell script which were previously separated by sleep to ensure that they were run in order.
# gpiodev.service
[Unit]
Description=Handle gpiodev kernel module
After=home-root-linux.mount
Before=mysqlsafe.service
[Service]
Type=oneshot
ExecStartPre=/home/root/linux/mem_driver/memdev_load
ExecStart=/sbin/insmod gpiodev.ko; /bin/mknod /dev/gpiodev c 249 0
WorkingDirectory=/home/root/linux/gpio_driver
RemainAfterExit=yes
StandardOutput=journal
[Install]
WantedBy=multi-user.target
Second part of the systemd service (following the sleep). We have a separate shellscript which is placed in /sbin/ in this example as it contains a while loop so it would be best to separate this:
# mysqlsafe.service
[Unit]
Description=MySQL safe
After=gpiodev.service
Before=npmoutput.service
[Service]
Type=oneshot
ExecStart=/sbin/mysqlsafe.sh
WorkingDirectory=/home/root/src/control
RemainAfterExit=yes
StandardOutput=journal
[Install]
WantedBy=multi-user.target
Second part of the shell script which is executed in the systemd service above (separated to a separate file due to the complexity):
# /sbin/mysqlsafe.sh
#!/bin/sh
mysqld_safe &
up=0
while [ $up -ne 2 ]
do
up=$(pgrep mysql | wc -l);
echo $up
done
Third part of the systemd service (the third section of the original shell script which was separated by sleep):
# mpmoutput.service
[Unit]
Description=npm and output to log
After=mysqlsafe.service
[Service]
Type=oneshot
ExecStartPre=/usr/bin/npm &
ExecStart=/home/root/src/control > /home/root/linux/output.log
WorkingDirectory=/home/root/studio_web/myapp
RemainAfterExit=yes
StandardOutput=journal
[Install]
WantedBy=multi-user.target
The idea behind this approach is that systemd recognises the importance of each service and the reliance upon the following service i.e. if one service fails the following services in queue will not execute. You can then check this using systemctl and see logging in journalctl.
Just a quick copy, paste and edit. Could contain errors as it was not tested or checked.
More reading can be found here regarding systemd service files: https://www.freedesktop.org/software/systemd/man/systemd.service.html