Corrected notes on the feeding of yes to yes

This morning, I posted M Tang`s funny experiment in feeding the Unix "yes" command to itself. Now, Seth David Schoen writes in to correct and expand upon the principles therein:

M. Tang`s business about the Unix command

yes `yes no`

is based on a bit of a misconception. The problem is _not_ about combining one yes command with another yes command. Whenever you use the backtick syntax `, like in a hypothetical command

foo `bar`

the shell will first run the command bar (to completion) before it even tries to start foo. The shell will also save the complete output of bar in memory, and then present it as a set of command-line arguments to foo.

In this case, the shell is trying to run the command "yes no" to completion, saving its output in memory, before even starting the other yes command. Of course, "yes no" never finishes, but it does use up an arbitrarily large amount of memory.

To see that the problem is with the use of `yes` rather than with the combination of two yes commands, just try

echo `yes no`

or even

true `yes no`

Both of these forms have exactly the same memory-consumption problem as the original command, and for exactly the same reason! So, Tang is wrong to think that he is somehow creating a problem by combining multiple yesses. The problem is in asking the shell to remember an infinite amount of output.

As other people have mentioned in comments, the ` syntax is also not piping. Piping is done with |, while ` refers to substitution. The distinction is whether the output of program A appears as input to program B (piping) or as command-line arguments to program B (substitution). For example,

echo foo bar | wc -w

outputs the number 2 (that`s the total number of words in the text "foo bar"), while

wc -w `echo foo bar`

counts the number of words in the files foo and bar.



  1. yes | xargs -n 1 -P 0 yes 

    Might be a little closer to what the original author was after, but it won’t crash your system. A ctrl-c will recover things, but anyone else on the system who tries to do anything will get a bunch of “resource unavailable” errors.

    1. Yeah, it really makes a difference. 
      yes ‘yes no’ will just print
          yes no
      a lot of times. 
      yes `yes no` executes the stuff in the backtick, and the shell uses it to build an argument string for the outer yes command. 
      The stuff in the backquotes prints
      an infinite number of times.  In an old-fashioned Unix shell, there’s a limit to how big a command line can be, so the shell would probably accumulate the first 1023 or so bytes of “no”, maybe strip the newlines, and fork the outer “yes” command with that as input.  Fancier shells may use malloc to build a much larger character string to buffer the infinite amount of “no”, but it shouldn’t bother the operating system any more than any other command that’s leaking memory (but since it’s your shell, it won’t give a prompt back and might not be good at responding to ^C.)

      I tried it with bash, and the shell complained about not being able to allocate more than [some big number] of bytes and crashed.
      Apparently the standard /bin/sh on Ubuntu is dash, and it ran for a while and then complained “Segmentation fault (core dumped)” which is also a pretty classic error message.

  2. We should probably have a correction on the correction, describing which character is a backtick. `

  3. I thought the backticks were being deprecated, anyway.  Shouldn’t the syntax be:
    yes $(yes no)

  4. M:   Ah. I’d like to have an argument, please.
    R:    Certainly sir. Have you been here before?
    M:   No, I haven’t, this is my first time.
    R:     I see. Well, do you want to have just one argument, or were you thinking of taking a course?


Comments are closed.