Rust's equivalent of C's system('pause')

So admittedly i'm spoiled by Visual Studio and the Rust plugin for it is fantastic but I would like to 'elegantly' make the program pause at the end before closing, similar to C/C++'s "Press any key to continue" which is provided by System('pause').

I know I could just ask for additional input at the end, but that seems a little clunky to me. Is there such a thing in Rust lang at the moment?

The literal equivalent would probably be:

use std::process::Command;

let _ = Command::new("pause").status();

This constructs a new Command object to execute an external command, and executes it, discarding the result since we don't really care what it returned. I say "probably" because I'm not on Windows and can't test it; it's possible that this won't work if pause is a shell builtin rather than an external command.

Of course, this isn't portable, but I don't know if there is any portable way to get a single character of input for a "Press any key to continue" prompt.

1 Like

Pause is a command on Windows, but it should work with :
let _ = Command::new("cmd.exe").arg("/c").arg("pause").status()

2 Likes

Calling an OS-specific shell command to prompt for input for you is more clunky than just doing it yourself, IMO.

use std::io;
use std::io::prelude::*;

fn pause() {
    let mut stdin = io::stdin();
    let mut stdout = io::stdout();

    // We want the cursor to stay at the end of the line, so we print without a newline and flush manually.
    write!(stdout, "Press any key to continue...").unwrap();
    stdout.flush().unwrap();

    // Read a single byte and discard
    let _ = stdin.read(&mut [0u8]).unwrap();
}

fn main() {
    // Do some stuff
    pause();
}
11 Likes

The problem is that without platform-specific methods to enable raw input, you'll only see input once "enter" has been pressed. So "Press any key to continue..." isn't accurate here. You could do this and say "Press enter to continue..." or "Press return to continue...", but you need something platform specific if you want any key to be able to dismiss it.

Can you pls provide example code!

termion works on all UNIXish OS

extern crate termion;

use termion::input::TermRead;
use termion::raw::IntoRawMode;
use std::io::{stdout, stdin, Write};

fn main() {
    println!("Press any key to continue...");
    let mut stdout = stdout().into_raw_mode().unwrap();
    stdout.flush().unwrap();
    stdin().events().next();
}

Thanks, what about Windows?

1 Like

no idea ! someone else may know

I will make this supportable for the crate I work on. Checkout https://github.com/TimonPost/crossterm/. It will work crossplatform in version 0.5.0.

1 Like

I'm not particularly fond of this hack, but for completeness's sake, I'd like to mention that someone on the unofficial Rust community Discord server wrote a crate for this Windows problem: dont_disappear.

This is not a windows problem. The very same would happen on linux systems as well (or even worse, not pop up a terminal at all!).

This is a problem of the user trying to start a terminal application from the GUI.

Terminal applications are meant to be started from a terminal.

1 Like

The difference is that on Windows a console window is opened up and then disappears after the program exits, whereas on unices a terminal program does nothing visible when opened from a GUI.

Also, Windows users are far less likely to know how to open a terminal in the first place.

1 Like

As I said, that's a user's problem, not one of the operating system.

In the contrary, Windows has an operating system feature in which it creates a terminal when a console program is double clicked on so the user can see the output. Other operating systems do not have this feature. Using this operating system feature properly requires certain behavior of console programs, namely that they don't exit until after the user has had an opportunity to view any important output. This makes the issue inherently an operating system issue.

2 Likes

Trying to be smarter than the user and fail with this is an operating system issue, yes.

Not knowing how to operate the system properly is still a user issue.

If windows would keep all those windows open that pop up during login at my office box and I had to close them manually... I had already quit my job...

I'm already annoyed by them popping up at all. Why can't they just run silently? Why isn't this default behaviour?

If an application needs to run without a console it's the developer's responsibility to compile it with the correct subsystem. If the developer didn't do that then Windows can't tell if standard I/O is important to the user or not. In my opinion Windows' behavior is the correct one.

Just in case anyone is interested in contributing to the discussion on crossterm...

Hah, I thought this thread looked familiar. The same question was asked more recently than 3 years ago... How to block console from exiting?

I previously noted that I would implement this behavior into crossterm. Crossterm 5.0 is now live with the ability to pause the terminal. See this example for more information.

1 Like