0

I'm trying to create a systemd unit file that will take an argument for a php script.

The small php script:

<?php
$val = $argv[1];

while(true) {
        echo "Argument = $val\n";
        sleep(1);
}
?>

Devs are working on the real script. All I need to do to test is take an argument, which is passed in the systemd unit file. Here it is:

[email protected]

[Unit]
Description=Systemd Params Test
Wants=network-online.target
After=network-online.target

[Service]
Environment=ARGS=%I
ExecStart=/usr/bin/php /home/myself/test_systemd.php $ARGS
StandardOutput=file:/var/log/test-multiple-systemd-$ARGS.log

[Install]
#Start after boot
WantedBy=multi-user.target

I start the multiple instances with systemctl start [email protected] and systemctl start [email protected]. When checking the services, I see:

root@servername:/lib/systemd/system# systemctl --type=service | grep test
[email protected]      loaded active running Systemd Params Test                                                          
[email protected]      loaded active running Systemd Params Test 

It is not creating the different log files. It's only creating a single one, strangely with quotes around it:

-rw-r--r-- 1 root root 285 Dec 8 08:15 'test-multiple-systemd-$ARGS.log'

And the content of the log file is mostly "Argument = bar". Only a few instances of "Argument = foo" for some reason:

cat /var/log/test-multiple-systemd-\$ARGS.log

Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = bar
Argument = foo <--- WHY???
Argument = foo
Argument = foo
Argument = foo
Argument = foo
Argument = foo

Is it possible to write to different log files for each instance of the systemd unit? I would like to see test-multiple-systemd-foo.log and test-multiple-systemd-bar.log if those are the arguments I pass. I've tried escaping the $ in the log path to no avail. I've tried removing and adding quotes to the Environment="$ARGS=%I" also to no avail. The log always shows with quotes with the literal "$ARGS" in the name.

UPDATE

It appears I cannot create the multiple log files dynamically, per this answer.

So, I created the log writing in the php script with:

echo file_put_contents("/var/log/test-multiple-systemd-$val.log", "Argument=$val", FILE_APPEND);

Will this suffice? I'm getting the multiple log files now and they are writing the argument correctly to the log file.

4
  • While starting a file from your script works, I would say that using the systemwide /var/log directory for a bash script could be unsafe, and you still have to contend with unexpected stderr/stdout coming from the script. Did you consider just using the journal and systemd-cat or logger in your script?
    – Gerrit
    Dec 8, 2021 at 16:35
  • This is not a permanent log path. I'm just testing on a dev server. :) The logs are in a subdirectory of /var/log/. They've existed for quite some time, but now they're wanting multiple instances of the same script. Dec 8, 2021 at 16:48
  • It probably doesn't make sense to put the ARGS into the environment, if you already include this info on the ExecStart line. Just use '%i" in the ExecStart line and be done with it. Prefer %i here, because otherwise you could have an escape of the quotes and unwanted globbing and word splitting by the shell. Not an issue if you only use numbers, but higly recommended for more general usage of these methods of passing the instance variable.
    – Gerrit
    Dec 8, 2021 at 16:59
  • Also look here for an idea how to package your instances into a target that can run a defined set of them: stevenrombauts.be/2019/01/…
    – Gerrit
    Dec 8, 2021 at 17:02

1 Answer 1

0

You should fix your .service file for several log files. Variables should be with braces {}. Like this:

ExecStart=/usr/bin/php /home/myself/test_systemd.php ${ARGS}
StandardOutput=file:/var/log/test-multiple-systemd-${ARGS}.log

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .