Inconsistent stderr output between shell and systemd - python-3.x

I have a little script running at startup:
At first i was using crontab with #reboot tag, but, since some time i need to modify the script, i ended up looking at systemd for an easy restart of the script
my crontab config was:
#reboot sleep 10; cd /path/to/the/script/ && nohup ./script.py >> stdout.txt 2>> stderr.txt
and everything was working fine
I'm now using systemd with this config:
[Unit]
Description=Script
[Service]
WorkingDirectory=/path/to/the/script/
ExecStart=/path/to/the/script/script.py
StandardOutput=file:/path/to/the/script/stdout.txt
StandardError=file:/path/to/the/script/stderr.txt <----- Problem here
User=my_user
[Install]
WantedBy=graphical.target
the problem is:
before stderr was correctoly written to stderr.txt
now both stdout and stderr are written to stdout.txt, even if i specified a different file for stderr
There are also no errors looking at
journalctl -e -u python-coolosseo
BTW i tried both file: and append:

Related

Running bash script as a service and write to another bash script is not working

I have the following problem using bash script.
Here is what I have inside the 'startup' script file:
#!/bin/bash
java -cp ../lib/online-store.jar:../lib/* com.online.store.Main
OnlineStorePID=$!
if [$OnlineStorePID -ne 0] then
echo "kill $OnlineStorePID" > shutdown
fi
Basically what I do, is to run a java application, get the process id and write it to another bash file. All this process works when I execute the startup script, and the 'shutdown' script file is updated successfully with a line containing 'kill processIDNumber' cmd.
Now I have tried to create a service on Ubuntu for this script using the following commands:
sudo systemctl daemon-reload
sudo systemctl enable online-store.service
sudo systemctl start online-store
When I start the service the java application starts successfully, but the shutdown script file is not updated. It seems that the 'echo "kill $OnlineStorePID" > shutdown' line is not executed. I don't get any complain errors. Does anyone knows what's the problem here.
Here is my service file:
[Unit]
Description=Online store service
Requires=multi-user.target
After=multi-user.target
Wants=mysql.service
[Service]
WorkingDirectory=/home/user/Desktop/online-store-service
#path to executable.
ExecStart=/home/user/Desktop/online-store-service/bin/startup
ExecStop=/home/user/Desktop/online-store-service/bin/shutdown
SuccessExitStatus=143
TimeoutStopSec=10
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
Change your script and run the java command like below as back ground process
java -cp ../lib/online-store.jar:../lib/* com.online.store.Main >/dev/null 2>&1 &

How to Pipe Output to a File When Running as a Systemd Service?

I'm having trouble piping the STDOUT & STDERR to a file when running a program as a systemd service. I've tried adding the following to the .service file:
ExecStart=/apppath/appname > /filepath/filename 2>&1
But this doesn't work. The output is ending up in /var/log/messages and is viewable using journalctl but I'd like a separate file.
I've also tried setting StdOutput=tty but can't find a way of redirecting this to a file.
Any help would be appreciated.
systemd.service(5) says:
ExecStart=
Commands with their arguments that are executed when this service is started.
So, systemd runs your /apppath/appname with args >, /filepath/filename, 2>&1
Try:
ExecStart=/bin/sh -c '/apppath/appname > /filepath/filename 2>&1'
Try:
ExecStart=/usr/bin/sh -c "/apppath/appname > /filepath/filename 2>&1"
ExecStart requires the first argument to be a binary (no exceptions), and doesn't allow pipes or redirection. Therefore, use ExecStart to start a shell within which you can do all the fancy things required.

How to run last and print my script output during boot with systemd?

I’m trying to configure my host during deployment process and to give an output to the screen of what my configuration script is doing.
In RHEL6 it was easy i was echoing what I want to screen or used dialog to display the output, and only when my script was done i got the login prompt.
( I used rc3.d or rc5.d folder with script name S99.myscript.sh)
In RHEL7 i can’t mimic this process.
rc.local does not display my output during booting and also its not guaranteed it will run last.
I guess I need to create a systemd service file that will run my script.
But how do I output the result to the screen while booting?
And how do I make sure I will not get the log-in prompt before my script ends?
below service example works like a charm :)
[Unit]
Description=ldt_bootscript1.service
After=network.target
Before=getty#tty1.service
[Service]
Type=oneshot
ExecStart=/bin/bash -c "/bin/bash /tmp/ldt_scripts/postinstall/rc.firstboot.qas | /usr/bin/dialog --clear --backtitle \"Linux Deployment\" --title \"tests\" --progressbox 20 70 > /dev/console 2>&1"
ExecStartPre=/usr/bin/echo -e \033%G
ExecReload=/bin/kill -HUP $MAINPID
RemainAfterExit=no
WorkingDirectory=/
Environment=TERM=xterm
[Install]
WantedBy=multi-user.target

UPSTART script non root not working

I'm trying to run a nodejs application using upstart as a non root user.
But somehow parts of the script will not run : for instance:
if I run it like a root user(below example) NODE_ENV never gets called/set
the only way to called is with "sudo initctl stop pdcapp"
sudo nameofApp start|stop would not work
When called sudo initctl stop nameofApp the pre-stop script will not echo to the log file
if I try to runit like a non root user it would not even start
isn't a more cleaner easier way of doing this (systemd) I've looked a various tutorials around and apparently this is how they've doneit. so what am I missing here?
This is the .conf file under /etc/init/
env FULL_PATH="/srv/pd/sept011100/dev"
env NODE_PATH="/usr/local/nodeJS/bin/node"
env NODE_ENV=production
start on filesystem or runlevel [2345]
stop on [!2345]
script
export NODE_ENV #this variable is never set
echo $$ > /var/run/PD.pid
cd $FULL_PATH
# the command below will not work
#exec sudo -u nginx "$NODE_PATH server.js >> /var/log/PD/pdapp.log 2>&1"
exec $NODE_PATH server.js >> /var/log/PD/pdapp.log 2>&1
end script
pre-start script
echo "[`date`] (sys) Starting" >> /var/log/PD/pdapp.log
end script
pre-stop script
rm /var/run/pdapp.pid
echo "[`date`] (sys) Stopping" >> /var/log/PDC/pdapp.log
end script
in /var/log/messages I get this when I stop the application, otherwise I get nothing in the logfile
Sep 2 18:23:14 547610-redhat-dev2 init: pdcapp pre-stop process (6903) terminated with status 1
Sep 2 18:23:14 547610-redhat-dev2 init: pdcapp main process (6899) terminated with status 143
any Ideas why is this not working I'm running redhat 6.5
Red Hat has a super old version of Upstart that is probably full of bugs because they never contributed to Upstart, despite using it (Fedora switched to systemd right after RHEL 6 was released, before they even really tried it out well).

Multiline write fails (Permission denied)

I would like to write a multiline string to a file that is only accessible with root permissions.
This is what I have so far:
sudo cat > /etc/init/myservice.conf <<EOL
start on runlevel [2345]
stop on runlevel [06]
respawn
script
cd ~/somefolder
. venv/bin/activate
exec python manage.py runserver 0.0.0.0:8080
end script
EOL
When this command, all I get is "Permission Denied". Creating the file manually works.
The output redirection is processed before sudo runs, so you are still trying to open the file as yourself, not as root. One option is to use tee instead of cat, since tee, rather than the current shell, will open the file for writing.
sudo tee /etc/init/myservice.conf > /dev/null <<EOF
start on runlevel [2345]
stop on runlevel [06]
respawn
script
cd ~/somefolder
. venv/bin/activate
exec python manage.py runserver 0.0.0.0:8080
end script
EOF
While the delimiter used doesn't really matter, it makes more sense to use something that indicates end of file, rather than end of line :) tee actually writes its input to both the named file(s) and standard output, but you don't need to see what you are writing, hence the redirection to /dev/null.

Resources