I have a script to start java application on boot time.
[Unit]
Description=test Background
[Service]
ExecStart=/bin/bash -c "/usr/bin/java -jar /var/www/tset.com/*.jar"
Type=simple
WorkingDirectory=/var/www/test.com
[Install]
WantedBy=multi-user.target
Can we edit this to write pid into a file in specific location?
As an example,
ExecStart=/bin/bash -c "/usr/bin/java -jar /var/www/test.com/*.jar | echo $! > ${RUNNING_PID}"
You should be able to run java directly rather than running a bash shell that runs java. If you do that you can run the systemctl show command to get the PID
assuming of course that your java application doesn't create more processes.
If your service name file ends in .service then you can omit the .service suffix from
<your service name>
If you run via a bash script then you'll get the pid of the bash shell that's running your java process.
The way I'd approach this problem is this way:
There's a couple things that require attention:
what you're trying to do is to write
.pid
file which contains the PID of the process, and on Linux the "de facto" location is to put it into/var/run
The
>
operator is for redirectingstdout
ofecho
, which will be the contents of$$
or the shell PID.Why shell PID ? Well, that's because next thing we're using is
exec
command which will replace shell process with your java application. What was PID 1234 representing shell will now be 1234 representing java application.Such approach, while seems convoluted, is actually more appropriate:
ps
orpgrep
to find it, we don't have to apply complex parsing, nor we have a problem if there's multiple instances of the application running already ( which shouldn't be the case if you're using a systemd service to start it, but there's no harm in accounting for a possibility of that as well )exec
resources won't be wasted for starting multiple processes. When you have something likebash -c '/usr/bin/java -jar myapp.jar & pgrep -f myapp.jar > /var/run/myapp.pid '
that's 3 processes. In the above command suggested - we have one process replacing another.Of course, this is just an example. Adjust how necessary to your case, and
/var/run/tset.pid
is chosen here just as an example - naming is up to you as well as location of the file, though I'd recommend using/var/run
for consistency with other applications.Side note:
The
| echo $! > ${RUNNING_PID}"
part wouldn't be appropriate for at least one reason:${RUNNING_PID}
is a variable, however it is not declared anywhere, so it would be a replaced by plank in shell.|
is pointless -stdout
of java application is connected tostdin
ofecho
which in case where you want output of application sent to another application is appropriate, but echo does not readstdin
- i.e. here it is pointless.Of course, if the application itself ( i.e. the java application ) forks - i.e creates - another process the
$$
won't help much, though to be perfectly fair if the application does indeed create multiple forks then it probably should be the job of the application itself to create and manage the.pid
file and report main process pid.systemd leaves your process's pid on enviroment, so you can use it on your script: