Why does the -e
option behave differently when the script is written in /etc/rc.local
and when it is not?
For example, if you have a script like this and run caller.sh
, the echo-sleep5.sh
process disappears in seconds.
(/bin/sh
does not have dash
, no_such_command
and is intended to fail here.)
#!/bin/sh-e
/path/to/echo-sleep5.sh | no_such_command &
#!/bin/bash
# set-e
i = 0
while [true]; do
sleep5
echo "$i"
i = $(($i+1))
done
However, if you write the contents of caller.sh
in /etc/rc.local
, if you don't do set-e
in echo-sleep5.sh
, the process will continue.
What makes these differences?
The environment is started by Raspbian Jessie.systemd
via rc-local.service
.
I used the actual machine to investigate based on other people's comments.
The process remained the difference between ignoring SIGPIPE
.
set-e
behaves as designed
For example, if you run caller.sh with the following script, the echo-sleep5.sh process disappears in seconds.
The default behavior of the signal SIGPIPE
is to terminate the process. SIGPIPE
is not masked, so if a 書き込みwrite error: Brokenpipe が occurs, it receives SIGPIPE
and terminates the process.
However, if you write the contents of caller.sh in /etc/rc.local (Sivan is the same), if you don't set-e within echo-sleep5.sh, the process will continue.
What makes these differences?
Booting via rc-local.service in systemd will ignore the signal SIGPIPE
.Therefore, a "write error: Broken pipe" does not terminate the process.
I checked with strace and found that when I ran set-e
, the shell script terminated itself when it detected an error (exit_group(1)
).
Also, I checked to see if the signal is actually set to ignore.
When I ran cat/proc/self/status
in the script, the SigIgn line was as follows:
SigIgn:0000000000001006
(hexadecimal, where 1006 is a binary number of 0001000000000110)
The SIGPIPE
signal number is 13.
The 13th bit from the right is ON, so the SIGPIPE
is ignored.
Why does the -e option behave differently when the script is written to /etc/rc.local and when it is not?
The behavior of the -e option is not different.
If you write to /etc/rc.local, if you get a "write error: Broken pipe", the -e option will terminate the process, and the -e option will not terminate the process.
If you run it directly without writing it to /etc/rc.local, the process will terminate, whether you add the -e option or not.Even if you don't turn it on, it ends with a signal reception.
If you did not add the -e option, the process did not end when you tried ignoring the signal SIGPIPE
(trap""13).
This is an environment where you have verified its operation.
Raspbian GNU/Linux 10 (buster)
I checked with my hand (Ubuntu 16.04) and changed echo "$i"
from echo-sleep5.sh
to redirect echo "$i">/tmp/foo
, and caller.sh
from the command line also left the echo-sleep5.sh
process.
I haven't followed the lead yet, so I imagine it's the difference between whether or not I/O fails.
© 2024 OneMinuteCode. All rights reserved.