Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

This question already has an answer here:

If I run these commands:

dmesg | head -n 10

I presume the OS sends back some kind of signal to dmesg once head has read 10 lines. How does this work? What does head tell the kernel?

This is different from a program dying since this is a normal, 'clean' stop.

share|improve this question

marked as duplicate by muru, Anthon, Scott, Gilles, Braiam Jan 19 at 13:53

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

    
@muru: No, it's not a duplicated. That question about what, here is how and whether dmesg was killed after 10 lines. – cuonglm Jan 18 at 10:57
2  
@cuonglm what makes something do x is not necessarily equal to just what. – muru Jan 18 at 10:59
    
@muru: Yes, but reading that question, you only got some information about how, which was not the main purpose of this question. – cuonglm Jan 19 at 1:50
    
How do you know it's a normal, clean stop? – muru Jan 19 at 9:41
    
dmesg receives EPIPE, just as described in the duplicate answer. – roaima Jan 19 at 17:42
up vote 26 down vote accepted

It depends on the OS buffers and the timing between the 10th and 11th writes of dmesg.

After head writes 10 lines, it terminates and dmesg will receive SIGPIPE signal if it continues writing to the pipe.

Depending on your OS buffer, dmesg will often write more than 10 lines before head consumes them.

To see that head had consumed more than 10 lines, you can use:

strace -f sh -c 'dmesg | head -n 10'

(Look at the head process, count on number of read system calls.)

To see how the writing speed effect:

strace -f sh -c "perl -le '$|++;print 1 while 1' | head -n 10"
share|improve this answer
    
Technically, head terminates after it outputs 10 lines; it may consume more than 10 lines of input before doing so. – chepner Jan 18 at 18:17
    
@chepner: Yes, it's my typo, fixed. – cuonglm Jan 18 at 18:22

Take a look at the POSIX specification for the write() function:

The write() function shall fail if:

… An attempt is made to write to a pipe or FIFO that is not open for reading by any process, or that only has one end open. A SIGPIPE signal shall also be sent to the thread.

So the sequence of events is:

  1. The head process exits. This causes all its open file descriptors to be closed, including its standard input, which is one end of the pipe.

  2. The dmesg process calls write() on its standard output, which is the other end of the pipe.

  3. This causes a SIGPIPE to be delivered to the dmesg process.

  4. dmesg has no special handling of SIGPIPE, so the default action is applied, which is to terminate the process.

You can experiment with this by changing the action for the SIGPIPE signal. For example, this pipeline terminates after printing one line:

$ yes | head -1
y
$

but if you ignore SIGPIPE, then it doesn't terminate:

$ trap '' PIPE
$ yes | head -1
y

At this point the yes process is still trying to write to the pipe but the writes are failing with EPIPE.

share|improve this answer

head closes stdin after printing 10 lines. Then dmesg detects that the stdout is closed and exits.

To be more precise, dmesg will receive the EPIPE error from the write call to stdout.

From the dmesg.c source code here: https://github.com/karelzak/util-linux/blob/v2.27.1/sys-utils/dmesg.c#L654-L659

rc = fwrite(p, 1, len, out) != len;
if (rc != 0) {
    if (errno != EPIPE)
        err(EXIT_FAILURE, _("write failed"));
    exit(EXIT_SUCCESS);
}
share|improve this answer
1  
Highly unlikely dmesg will receive EPIPE. It's more likely dmesg will receive a SIGPIPE, and terminate. – muru Jan 18 at 10:55
    
You are right, dmesg will receive SIGPIPE and will exit with an error (it does not trap that signal). – zuazo Jan 18 at 11:18

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