29

The full portion of the Bash man page which is applicable only says:

If the operating system on which bash is running supports job control, bash contains facilities to use it. Typing the suspend character (typically ^Z, Control-Z) while a process is running causes that process to be stopped and returns control to bash. Typing the delayed suspend character (typically ^Y, Control-Y) causes the process to be stopped when it attempts to read input from the terminal, and control to be returned to bash. The user may then manipulate the state of this job, using the bg command to continue it in the background, the fg command to continue it in the foreground, or the kill command to kill it. A ^Z takes effect immediately, and has the additional side effect of causing pending output and typeahead to be discarded.

I have never used Ctrl-Y; I only just learned about it. I have done fine with Ctrl-Z (suspend) only.

I am trying to imagine what this option is for. When would it be useful?

(Note that this feature doesn't exist on all Unix variants. It's present on Solaris and FreeBSD but not on Linux. The corresponding setting is stty dsusp.)

Perhaps less subjectively: Is there anything that can be accomplished with Ctrl-Y that cannot be accomplished just as easily with Ctrl-Z?

  • @Gilles, though FreeBSD seems to have a stty dsusp, I've not managed to make it send a SIGTSTP upon ^Y (I did on Solaris). Have you? – Stéphane Chazelas Aug 17 '16 at 9:53
23

From the 4BSD manual for csh:

A ^Z takes effect immediately and is like an interrupt in that pending output and unread input are discarded when it is typed. There is another special key ^Y which does not generate a STOP signal until a program attempts to read(2) it. This can usefully be typed ahead when you have prepared some commands for a job which you wish to stop after it has read them.

So, the purpose is to type multiple inputs while the first one is being processed, and have the job stop after they are done.

  • This description is subtly different from the bash manual. "...does not generate a STOP signal until a program attempts to read it." It sounds like everything in the input stream up to the ^Y will be read successfully, and then when the ^Y is hit the process will be stopped. Am I reading this right? – Wildcard Sep 15 '16 at 23:30
  • @Wildcard in my test on Mac OS X, the process is stopped before read() returns (but after the call to read() that would have returned the Y runs), and after it is resumed it receives the input from before ^Y. I think as this was intended to be used, though, it would be used at the start of a line, so the behavior in this case would not matter. I suspect that in the actual code, it is suspended when the ^Y would have been copied into the user process read buffer. – Random832 Sep 16 '16 at 2:41
  • I was right, in the original BSD kernel's ttread function you can see this, and modern OSX – Random832 Sep 16 '16 at 3:02
  • But, when the process is resumed, the call will succeed and will contain the data you typed into your terminal before ^Y, even if you have disowned the process and closed your terminal before the process is resumed. Right? ("...after it is resumed it receives the input from before ^Y." That's what I meant; I don't usually deal in C code.) :) – Wildcard Sep 16 '16 at 3:34
  • Yes. And it returns without a newline at the end, which is unusual for a read in canonical mode [similar to if you'd typed some text and then pressed ^D once] I suspect they didn't think about this case very much, since it's really intended to be typed at the start of a line. – Random832 Sep 16 '16 at 3:37
11

Say there's a loop reading input and executing. It may be useful to let the task finish the current instruction it computes, without interrupting it before it gets back to the command line for a new one. So thus to end a cycle. This ends the loop gracefully and prevents it from running again if read is under a timeout restriction.

  • But if it's going to try to read input from the terminal anyway, it will stop at that point (and wait for your input), and you can ^Z it then. – Wildcard Aug 16 '16 at 3:07
  • Yes. See update. – Tomasz Aug 16 '16 at 3:10
  • Check one more. @Wildcard – Tomasz Aug 16 '16 at 3:26
  • 1
    But if it's got a timeout, wouldn't it also just end gracefully if you did nothing special? – Daniel Wagner Aug 16 '16 at 16:59
  • 1
    It might. But it might also go on and do some default job. – Tomasz Aug 16 '16 at 17:04
4

I can think of one scenario where it might be useful, but it's something of a contrived edge-case.

Suppose you're debugging a script that is writing temporary files that you wish to analyze before they're deleted as part of a clean-up routine.

You could add a read foo somewhere after the files are written (but before the cleanup), run the script, and press Ctrl-Y as they're being generated. You will then be dropped to a prompt with the script suspended in the background to do whatever you need to do, and can then fg to allow the script to complete.

  • 1
    Seems unlikely, because the script will wait for input anyway. So you could just as easily watch for it to prompt you for input and then suspend it with ^Z. In other words: after you type fg you will have to give the script some input anyway before it will continue. Hence my question; I still don't see the point of ^Y. (Thanks for answering, though!) :) – Wildcard Aug 16 '16 at 2:51
2

The only scenario I can think of (and even I don't find it very convincing), is if you want to use some type-ahead for a shell command. Say some command is running which will read input some time in the future. Then you can ^Y it, and then immediately type the next shell command that you want to have executed when the running command suspends. I don't think I have ever really used this in several decades of using BSD Unix.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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