4

I'm writing a service which should start LTE connection.

But the utility I'm using to connect (sakis3g) is writing to /dev/stderr, which is not available in systemd and the log is full of

Cannot create /dev/stderr: No such device or address

Is there some way to work around it?

Changing the utility script/binary is unfortunately not an option.

EDIT: Here is the service:

[Unit]
Description=LTE
After=syslog.target network-online.target
Before=openvpn-client@client
Wants=network-online.target

[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/opt/mav/LTE/
ExecStartPre=/sbin/ip link set wwan0 down
ExecStart=/opt/mav/LTE/sakis3g connect -g --sudo
ExecStop=/opt/mav/LTE/sakis3g disconnect --sudo

[Install]
WantedBy=multi-user.target

And it works in this state. But when I start sakis3g with -g flag for more verbose debug output, then the stderr errors appear.

  • You should provide more information about your .service file. – Valentin Bajrami Oct 30 '17 at 10:41
4

If there was no stderr, you wouldn't see the error.

Here, the error is about not being able to open the /dev/stderr file, which on Linux is a symlink to the actual file that is open on the fd 2 (while on other systems, opening /dev/stderr is like doing a dup(2)).

The problem here is likely that fd 2 is open on a socket (inet TCP, Unix stream or other) and you can't open() a socket file.

If you run:

sudo lsof -aU +E -d 2

On a system using systemd you'll notice that fd 2 of most services is a unix domain stream socket to systemd-journald.

As a work around, you may be able to start it as:

bash -o pipefail -c '{ /opt/mav/LTE/sakis3g connect -g --sudo 2>&1 >&3 3>&- | cat >&2 3>&-; } 3>&1'

That is make stderr a pipe (to cat) instead of a socket, cat forwarding what it receives on the pipe to the original stderr (the socket), and make sure we preserve the exit status of the command with the pipefail option.

In any case, the source of that sakis3g is available and that sakis3g init file is a bash script, that happen to do:

echo text >> /dev/stderr

instead of:

echo test >&2

It's even got a few > /dev/stderr instead of >> /dev/stderr which is even more wrong. It has no tee -a /dev/stderr | other cmd which would have been a legitimate use of /dev/stderr and would also not work with stderr on a socket, so it's easily fixable.

You may want to let them know of the problem by raising an issue at https://github.com/Trixarian/sakis3g-source/issues

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.