Question:
$ cat pseudo-yes.sh
#!/bin/sh
while true; do
printf "y\n"
done
$
I pseudo-yes.sh
as above. If you use this, for example, as follows, it will behave like a yes
command without any problem.
$ ./pseudo-yes.sh | head -n 1
y
$
From this behavior, it can be understood that the SIGPIPE
signal generated when executing the printf
command should be received and processed by pseudo-yes.sh
. (Otherwise, you can't get out of the while
statement)
I understand that the SIGPIPE
signal should be issued to the process that made the write
system call.
question:
- Why is
pseudo-yes.sh
able to handleSIGPIPE
correctly even though the main process that writes isprintf
?
supplement:
- This behavior was observed on both ubuntu and mac-os-x.
Answer: Answer:
printf
is a shell built-in command for both Ubuntu /bin/sh
(bash, dash or posh) and Mac OS X /bin/sh
(bash).
$ /bin/sh -c 'type printf'
printf is a shell builtin
Also, SIGPIPE
's default signal handler is process termination. So when you execute the code in question, the /bin/sh
process receives a SIGPIPE
signal and exits.
On Ubuntu, if you execute the following, /bin/sh
does not start the external command.
(Don't execute system calls fork
(2), clone
(2), execve
(2)),
You can observe that you are receiving SIGPIPE
.
$ strace -f /bin/sh -c 'while true; do printf "y\n"; done' |head -n 1
Therefore, it works as expected.
Assuming that printf
is not built-in /bin/sh
, let's end it if the exit code of printf
is other than 0 as follows. If the printf
(1) process exits after receiving SIGPIPE
, the exit code will be 128 + an integer value of SIGPIPE
(typically 13) = 141.
#!/bin/sh
while true; do
printf "y\n" || exit $?
done