Writing strings to input

hi, how do i write to input? for example:

C:\Users\username>

to:

C:\Users\username>cd something

and auto press enter.
may i know how this can be achieved without bringing in batch files? thank you!

Disclaimer first: I come from a unix perspective, so my terminology may be off, and hopefully I don't make any gross technical errors.


Next, let's get some general context out of the way.

When you're looking at a prompt, you're in a shell -- which is a program running on your computer. It shows you the working directory, and it lets you run other commands. Some of those commands are separate programs, and some of those commands are instructions for the shell you're in -- set this environment variable, change to this directory, and so on.

When you run another program, like a Rust program you wrote say, the shell doesn't take commands from it really. It will wait for the program to finish typically (though you can run programs in the background too), and then redisplay the prompt and start taking commands from you again. So there's no way to send instructions back to the thing that started your program.

Moreover, as a running Rust program, it may be the case that you weren't even started from a shell. Maybe you were started from a GUI, or a scheduled task, or another non-shell program started you, etc. The shell is not some intrinsic environment that must be present for every other running program. There are such environments for most programs -- the system library or at least the system kernel -- but a shell is not one of them.


OK, with that context -- what are you trying to actually accomplish? You can't send commands back to the shell that launched you (if there even is one), but you can accomplish things that you could do in a shell.

If you need to change the working directory of your process, you can use std::env::set_current_dir. If you need to run a bunch of other commands, you'll want to check out std::process::Command. And if you wanted to, you could even write a batch file to disk somewhere and then execute that (probably using Command).

If you need to do something else, you'll probably have to be more specific.

4 Likes

In bash land we hit tab twice to bring up auto-completion or another trick, ctrl-r for a reverse search or command history.
In windows, I think tab twice also will bring up tab completion.

For your history in windows I think maybe the following.

doskey /history

Are you wanting to inject keystrokes / mimic a human typing?

i have tried Command, however i am unable to input multiple commands:

Command::new("cmd", "/k", "mkdir folder", "mkdir sub", "rd /s folder2");

does not work.

Hi!

The Command perform only one command at a time. If you want to process multiple commands, you'll have to do with multiple processes.

You can also specify the directory where you want to execute the command with current_dir.

    let commands = [
        [".", "mkdir folder"],
        ["./folder", "mkdir subfolder"],
        [".", "mkdir bar"],
    ];
    for cmd in commands {
        let a: Vec<String> = cmd[1].split(' ').map(|s| s.to_string()).collect();
        Command::new(&a[0])
            .current_dir(cmd[0])
            .args(&a[1..])
            .output()
            .expect("command failed");
    }

Each arg passed to the Command instance is an input parameter, so if you try that:

    Command::new("mkdir")
        .current_dir(".")
        .arg("folder")
        .arg("&&")
        .arg("cd")
        .arg("folder")
        .arg("&&")
        .arg("mkdir")
        .arg("subfolder")
        .output()
        .expect("command failed");
}

It will not execute multiple commands, but only the first mkdir with each args as a parameter. In addition, if you want to do something like a sigkill or something tricky like ctrl-z I guess you could use the nix crate or another implementation of Command like in the tokio crate. But I don't think you can do an "autocomplete" signal.

i see, thank you!

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.