Understanding Shell -e Options and rc.local

Asked 2 years ago, Updated 2 years ago, 86 views

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.

shellscript

2022-09-30 14:23

2 Answers

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)


2022-09-30 14:23

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.


2022-09-30 14:23

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.