### Initialize and Run Shell Commands Source: https://docs.rs/expectrl/0.8.0/expectrl/repl/struct.ReplSession.html This example demonstrates the complete setup and execution flow for a shell session using `ReplSession`. It includes spawning the shell, configuring it, executing commands, and printing their output. ```rust fn main() -> Result<()> { let mut p = expectrl::spawn("sh")?; p.set_echo(true)?; let mut shell = ReplSession::new(p, String::from("sh-5.1$")); shell.set_echo(true); shell.set_quit_command("exit"); shell.expect_prompt()?; let output = exec(&mut shell, "echo Hello World")?; println!("{:?}", output); let output = exec(&mut shell, "echo '2 + 3' | bc")?; println!("{:?}", output); Ok(()) } ``` -------------------------------- ### Interactive Callback Example Source: https://docs.rs/expectrl/0.8.0/expectrl/interact/actions/lookup/struct.Lookup.html This example showcases the use of callbacks for handling input and output during interactive sessions with a spawned process. ```APIDOC ## POST /examples/interact_with_callback.rs ### Description This example demonstrates how to use ExpectRL with custom input and output actions (callbacks) to manage an interactive session with a Python script. ### Method POST ### Endpoint /examples/interact_with_callback.rs ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```json { "example": "No request body for this example" } ``` ### Response #### Success Response (200) - **output** (string) - The final output from the interactive session, including state information. #### Response Example ```json { "example": "RESULTS\nNumber of time 'Y' was pressed = X\nStatus counter = Y" } ``` ``` -------------------------------- ### FTP Interaction Example Source: https://docs.rs/expectrl/0.8.0/expectrl/interact/actions/lookup/struct.Lookup.html This example demonstrates how to use ExpectRL to interact with an FTP client process, including authentication and file operations. ```APIDOC ## POST /examples/ftp_interact.rs ### Description This example demonstrates how to use ExpectRL to interact with an FTP client process, including authentication and file operations. ### Method POST ### Endpoint /examples/ftp_interact.rs ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```json { "example": "No request body for this example" } ``` ### Response #### Success Response (200) - **output** (string) - The output from the FTP process. #### Response Example ```json { "example": "FTP session output and status messages" } ``` ``` -------------------------------- ### Interact with a Shell Process Source: https://docs.rs/expectrl/0.8.0/expectrl/session/struct.Session.html This example demonstrates how to interact with a spawned shell process, allowing for interactive input and output management. ```APIDOC ## POST /interact/shell ### Description Initiates an interactive session with a spawned shell process. This allows for real-time input and output handling. ### Method POST ### Endpoint /interact/shell ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **stdin** (Stdin) - Required - A mutable reference to the standard input stream. - **stdout** (Stdout) - Required - A mutable reference to the standard output stream. ### Request Example ```json { "stdin": "", "stdout": "" } ``` ### Response #### Success Response (200) - **is_alive** (bool) - Indicates if the interactive session is still active. - **status** (Option) - The exit status of the process if it has terminated. #### Response Example ```json { "is_alive": true, "status": null } ``` ``` -------------------------------- ### Interact with FTP Process with Callbacks Source: https://docs.rs/expectrl/0.8.0/expectrl/session/struct.Session.html This example shows how to interact with an FTP process, including setting custom output and input actions (callbacks) to handle specific prompts and user inputs. ```APIDOC ## POST /interact/ftp ### Description Establishes an interactive session with an FTP client. This method allows for defining custom logic for handling prompts (e.g., login, commands) and user responses. ### Method POST ### Endpoint /interact/ftp ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **stdin** (Stdin) - Required - A mutable reference to the standard input stream. - **stdout** (Stdout) - Required - A mutable reference to the standard output stream. - **state** (State) - Required - A mutable reference to a custom state object to track session information. - **output_action** (Lookup) - Optional - A lookup object defining actions to take based on process output. - **input_action** (Lookup) - Optional - A lookup object defining actions to take based on user input. ### Request Example ```json { "stdin": "", "stdout": "", "state": {"wait_for_continue": null, "pressed_yes_on_continue": null, "stutus_verification_counter": null}, "output_action": {"patterns": []}, "input_action": {"patterns": []} } ``` ### Response #### Success Response (200) - **is_alive** (bool) - Indicates if the interactive session is still active. - **status** (Option) - The exit status of the process if it has terminated. #### Response Example ```json { "is_alive": false, "status": {"code": 0} } ``` ``` -------------------------------- ### Interact with a process and handle output actions Source: https://docs.rs/expectrl/0.8.0/expectrl/interact/actions/lookup/struct.Lookup.html This example demonstrates setting up an `InteractSession` with a custom output action. The action uses `Lookup::on` to check for specific output patterns and update the session's state accordingly. It includes logic for handling login success and status verification. ```rust p.interact(&mut stdin, stdout()) .with_state(&mut auth) .set_output_action(move |ctx| { if login_lookup .on(ctx.buf, ctx.eof, "Login successful")? .is_some() { **ctx.state = true; return Ok(true); } Ok(false) }) .spawn()?; ``` ```rust let mut interact = session.interact(&mut stdin, stdout).with_state(&mut state); interact .set_output_action(move |ctx| { let m = output_action.on(ctx.buf, ctx.eof, "Continue [y/n]:")?; if m.is_some() { ctx.state.wait_for_continue = Some(true); }; let m = output_action.on(ctx.buf, ctx.eof, Regex("status:\s*.*\w+.*\r\n"))?; if m.is_some() { ctx.state.stutus_verification_counter = Some(ctx.state.stutus_verification_counter.map_or(1, |c| c + 1)); output_action.clear(); } Ok(false) }) ``` -------------------------------- ### Using Any::boxed in a loop Source: https://docs.rs/expectrl/0.8.0/expectrl/struct.Any.html Example of using Any::boxed to handle multiple termination conditions in a session loop. ```rust fn main() { let mut p = expectrl::spawn("ls -al").expect("Can't spawn a session"); loop { let m = p .expect(Any::boxed(vec![ Box::new("\r"), Box::new("\n"), Box::new(Eof), ])) .expect("Expect failed"); println!("{:?}", String::from_utf8_lossy(m.as_bytes())); let is_eof = m[0].is_empty(); if is_eof { break; } if m[0] == [b'\n'] { continue; } println!("{:?}", String::from_utf8_lossy(&m[0])); } } ``` -------------------------------- ### Spawn and Interact with a Python Script Source: https://docs.rs/expectrl/0.8.0/expectrl/interact/struct.InteractSession.html This example demonstrates how to spawn a Python script and interact with it using `InteractSession`. It sets up custom input and output actions to handle prompts and verify output, managing the session's state throughout the interaction. ```rust 13fn main() { 14 let mut output_action = Lookup::new(); 15 let mut input_action = Lookup::new(); 16 let mut state = State::default(); 17 18 let mut session = spawn("python ./tests/source/ansi.py").expect("Can't spawn a session"); 19 20 let mut stdin = Stdin::open().unwrap(); 21 let stdout = std::io::stdout(); 22 23 let (is_alive, status) = { 24 let mut interact = session.interact(&mut stdin, stdout).with_state(&mut state); 25 interact 26 .set_output_action(move |ctx| { 27 let m = output_action.on(ctx.buf, ctx.eof, "Continue [y/n]:")?; 28 if m.is_some() { 29 ctx.state.wait_for_continue = Some(true); 30 }; 31 32 let m = output_action.on(ctx.buf, ctx.eof, Regex("status:\s*.*\w+.*\r\n"))?; 33 if m.is_some() { 34 ctx.state.stutus_verification_counter = 35 Some(ctx.state.stutus_verification_counter.map_or(1, |c| c + 1)); 36 output_action.clear(); 37 } 38 39 Ok(false) 40 }) 41 .set_input_action(move |ctx| { 42 let m = input_action.on(ctx.buf, ctx.eof, "y")?; 43 if m.is_some() { 44 if let Some(_a @ true) = ctx.state.wait_for_continue { 45 ctx.state.pressed_yes_on_continue = Some(true); 46 } 47 }; 48 49 let m = input_action.on(ctx.buf, ctx.eof, "n")?; 50 if m.is_some() { 51 if let Some(_a @ true) = ctx.state.wait_for_continue { 52 ctx.state.pressed_yes_on_continue = Some(false); 53 } 54 } 55 56 Ok(false) 57 }); 58 59 let is_alive = interact.spawn().expect("Failed to start interact"); 60 61 (is_alive, interact.get_status()) 62 }; 63 64 if !is_alive { 65 println!("The process was exited"); 66 #[cfg(unix)] 67 println!("Status={{:?}}", status); 68 } 69 70 stdin.close().unwrap(); 71 72 println!("RESULTS"); 73 println!( 74 "Number of time 'Y' was pressed = {}", 75 state.pressed_yes_on_continue.unwrap_or_default() 76 ); 77 println!( 78 "Status counter = {}", 79 state.stutus_verification_counter.unwrap_or_default() 80 ); 81} ``` -------------------------------- ### Spawn a new session with expectrl Source: https://docs.rs/expectrl/0.8.0/expectrl/fn.spawn.html Use `spawn` to start a new process. It accepts a command as a string. For more complex configurations, use `Session::spawn`. ```rust use std::{thread, time::Duration, io::{Read, Write}}; use expectrl::{spawn, ControlCode}; let mut p = spawn("cat").unwrap(); p.send_line("Hello World").unwrap(); thread::sleep(Duration::from_millis(300)); // give 'cat' some time to set up p.send(ControlCode::EndOfText).unwrap(); // abort: SIGINT let mut buf = String::new(); p.read_to_string(&mut buf).unwrap(); assert_eq!(buf, "Hello World\r\n"); ``` -------------------------------- ### UnixProcess Process Implementation - Spawn Commandline Source: https://docs.rs/expectrl/0.8.0/expectrl/session/type.OsProcess.html Spawns a new process by parsing a command line string. This is a convenient way to start processes directly from a string. ```rust type Stream = PtyStream; fn spawn(cmd: S) -> Result where S: AsRef ``` -------------------------------- ### Interact with a spawned Python script using callbacks Source: https://docs.rs/expectrl/0.8.0/expectrl/interact/actions/lookup/struct.Lookup.html This example demonstrates how to spawn a Python script and interact with it using custom output and input actions defined by callbacks. It tracks user input for 'y/n' prompts and counts status messages. ```rust fn main() { let mut output_action = Lookup::new(); let mut input_action = Lookup::new(); let mut state = State::default(); let mut session = spawn("python ./tests/source/ansi.py").expect("Can't spawn a session"); let mut stdin = Stdin::open().unwrap(); let stdout = std::io::stdout(); let (is_alive, status) = { let mut interact = session.interact(&mut stdin, stdout).with_state(&mut state); interact .set_output_action(move |ctx| { let m = output_action.on(ctx.buf, ctx.eof, "Continue [y/n]:")?; if m.is_some() { ctx.state.wait_for_continue = Some(true); }; let m = output_action.on(ctx.buf, ctx.eof, Regex("status:\s*.*\w+.*\r\n"))?; if m.is_some() { ctx.state.stutus_verification_counter = Some(ctx.state.stutus_verification_counter.map_or(1, |c| c + 1)); output_action.clear(); } Ok(false) }) .set_input_action(move |ctx| { let m = input_action.on(ctx.buf, ctx.eof, "y")?; if m.is_some() { if let Some(_a @ true) = ctx.state.wait_for_continue { ctx.state.pressed_yes_on_continue = Some(true); } }; let m = input_action.on(ctx.buf, ctx.eof, "n")?; if m.is_some() { if let Some(_a @ true) = ctx.state.wait_for_continue { ctx.state.pressed_yes_on_continue = Some(false); } } Ok(false) }); let is_alive = interact.spawn().expect("Failed to start interact"); (is_alive, interact.get_status()) }; if !is_alive { println!("The process was exited"); #[cfg(unix)] println!("Status={{:?}}", status); } stdin.close().unwrap(); println!("RESULTS"); println!( "Number of time 'Y' was pressed = {}", state.pressed_yes_on_continue.unwrap_or_default() ); println!( "Status counter = {}", state.stutus_verification_counter.unwrap_or_default() ); } ``` -------------------------------- ### Interact with a process and handle input actions Source: https://docs.rs/expectrl/0.8.0/expectrl/interact/actions/lookup/struct.Lookup.html This example shows how to configure an `InteractSession` with a custom input action. The action uses `Lookup::on` to detect user input patterns ('y' or 'n') and modify the session's state based on the input. This is useful for controlling interactive prompts. ```rust .set_input_action(move |ctx| { let m = input_action.on(ctx.buf, ctx.eof, "y")?; if m.is_some() { if let Some(_a @ true) = ctx.state.wait_for_continue { ctx.state.pressed_yes_on_continue = Some(true); } }; let m = input_action.on(ctx.buf, ctx.eof, "n")?; if m.is_some() { if let Some(_a @ true) = ctx.state.wait_for_continue { ctx.state.pressed_yes_on_continue = Some(false); } } Ok(false) }); ``` -------------------------------- ### Execute Command in ReplSession Source: https://docs.rs/expectrl/0.8.0/expectrl/repl/struct.ReplSession.html The `exec` function (defined elsewhere in the example) is used to execute commands within the `ReplSession` and capture their output. It handles sending the command and waiting for the prompt. ```rust let output = exec(&mut shell, "echo Hello World")?; println!("{:?}", output); let output = exec(&mut shell, "echo '2 + 3' | bc")?; println!("{:?}", output); ``` -------------------------------- ### Usage of check macro Source: https://docs.rs/expectrl/0.8.0/expectrl/macro.check.html Example of using the check macro within a loop to handle different stream patterns. ```rust loop { expectrl::check!{ &mut session, world = "\r" => { // handle end of line }, _ = "Hello World" => { // handle Hello World }, default => { // handle no matches }, } .unwrap(); } ``` -------------------------------- ### Perform a lookup with a string pattern Source: https://docs.rs/expectrl/0.8.0/expectrl/interact/actions/lookup/struct.Lookup.html The `on` method checks if the provided buffer matches the given string pattern. It returns `Captures` if a match is found. This example demonstrates checking for a successful login message. ```rust if login_lookup .on(ctx.buf, ctx.eof, "Login successful")? .is_some() ``` -------------------------------- ### Perform a lookup with a Regex pattern Source: https://docs.rs/expectrl/0.8.0/expectrl/interact/actions/lookup/struct.Lookup.html The `on` method can also accept a `Regex` pattern for more flexible matching. This example shows checking for a status message using a regular expression. ```rust let m = output_action.on(ctx.buf, ctx.eof, Regex("status:\s*.*\w+.*\r\n"))?; ``` -------------------------------- ### Spawn a process using Command Source: https://docs.rs/expectrl/0.8.0/expectrl/index.html Shows how to initialize a session using a standard library Command object. ```rust use std::{process::Command, io::prelude::*}; use expectrl::Session; let mut echo_hello = Command::new("sh"); echo_hello.arg("-c").arg("echo hello"); let mut p = Session::spawn(echo_hello).unwrap(); p.expect("hello").unwrap(); ``` -------------------------------- ### Session Stream and Process Accessors Source: https://docs.rs/expectrl/0.8.0/expectrl/session/struct.Session.html Methods to get references to the underlying stream and process. ```APIDOC ## impl Session ### pub fn get_stream(&self) -> &S #### Description Get a reference to the original stream. ### pub fn get_stream_mut(&mut self) -> &mut S #### Description Get a mutable reference to the original stream. ### pub fn get_process(&self) -> &P #### Description Get a reference to the process running the program. ### pub fn get_process_mut(&mut self) -> &mut P #### Description Get a mutable reference to the process running the program. ``` -------------------------------- ### Session Stream and Process Access Source: https://docs.rs/expectrl/0.8.0/expectrl/session/type.OsSession.html Provides methods to get references to the original stream and the running process associated with a session. ```APIDOC ## GET /session/stream ### Description Get a reference to the original stream. ### Method GET ### Endpoint /session/stream ### Response #### Success Response (200) - **stream** (S) - A reference to the original stream. ## GET /session/stream/mut ### Description Get a mutable reference to the original stream. ### Method GET ### Endpoint /session/stream/mut ### Response #### Success Response (200) - **stream** (&mut S) - A mutable reference to the original stream. ## GET /session/process ### Description Get a reference to the process running the program. ### Method GET ### Endpoint /session/process ### Response #### Success Response (200) - **process** (P) - A reference to the running process. ## GET /session/process/mut ### Description Get a mutable reference to the process running the program. ### Method GET ### Endpoint /session/process/mut ### Response #### Success Response (200) - **process** (&mut P) - A mutable reference to the running process. ``` -------------------------------- ### Convert Raw Status to WaitStatus Source: https://docs.rs/expectrl/0.8.0/expectrl/process/unix/enum.WaitStatus.html Example of converting a raw status integer obtained from libc::waitpid into a WaitStatus enum variant. ```rust use nix::sys::wait::WaitStatus; use nix::sys::signal::Signal; let pid = nix::unistd::Pid::from_raw(1); let status = WaitStatus::from_raw(pid, 0x0002); assert_eq!(status, Ok(WaitStatus::Signaled(pid, Signal::SIGINT, false))); ``` -------------------------------- ### Spawn and interact with a process using Session Source: https://docs.rs/expectrl/0.8.0/expectrl/session/index.html Demonstrates spawning a process with Command and performing basic read/write operations. ```rust use std::{process::Command, io::prelude::*}; use expectrl::Session; let mut p = Session::spawn(Command::new("cat")).unwrap(); writeln!(p, "Hello World").unwrap(); let mut line = String::new(); p.read_line(&mut line).unwrap(); ``` -------------------------------- ### Retrieve match by index Source: https://docs.rs/expectrl/0.8.0/expectrl/struct.Captures.html Demonstrates using the get method on a Captures object to extract specific match groups from a regex result. ```rust 7fn main() { 8 let mut p = spawn_python().unwrap(); 9 10 p.execute("import platform").unwrap(); 11 p.send_line("platform.node()").unwrap(); 12 13 let found = p.expect(Regex(r"'.*'")).unwrap(); 14 15 println!( 16 "Platform {}", 17 String::from_utf8_lossy(found.get(0).unwrap()) 18 ); 19} ``` -------------------------------- ### Healthcheck Implementation for UnixProcess Source: https://docs.rs/expectrl/0.8.0/expectrl/session/type.OsProcess.html Provides health check capabilities for UnixProcess, including getting the process status and checking if it's alive. ```APIDOC ### impl Healthcheck for UnixProcess #### type Status = WaitStatus A status healthcheck can return. #### fn get_status(&self) -> Result The function returns a status of a process if it still alive and it can operate. #### fn is_alive(&self) -> Result The function returns a status of a process if it still alive and it can operate. ``` -------------------------------- ### Interact with an FTP server Source: https://docs.rs/expectrl/0.8.0/expectrl/index.html Demonstrates automating an FTP session using regex matching and sending commands. ```rust use expectrl::{spawn, Regex, Eof, WaitStatus}; let mut p = spawn("ftp speedtest.tele2.net").unwrap(); p.expect(Regex("Name \(.*\):")).unwrap(); p.send_line("anonymous").unwrap(); p.expect("Password").unwrap(); p.send_line("test").unwrap(); p.expect("ftp>").unwrap(); p.send_line("cd upload").unwrap(); p.expect("successfully changed.\r\nftp>").unwrap(); p.send_line("pwd").unwrap(); p.expect(Regex("[0-9]+ \"/upload\"")).unwrap(); p.send_line("exit").unwrap(); p.expect(Eof).unwrap(); assert_eq!(p.wait().unwrap(), WaitStatus::Exited(p.pid(), 0)); ``` -------------------------------- ### Spawning a Session Source: https://docs.rs/expectrl/0.8.0/expectrl/session/type.OsSession.html Details on how to spawn a new session by executing a command. ```APIDOC ## POST /session/spawn ### Description Spawns a session on a platform process. ### Method POST ### Endpoint /session/spawn ### Parameters #### Request Body - **command** (Command) - The command to execute. ### Request Example ```rust use std::process::Command; use expectrl::Session; let p = Session::spawn(Command::new("cat")); ``` ### Response #### Success Response (200) - **session** (Session) - The newly spawned session. #### Error Response (Error) - **error** (Error) - An error occurred during session spawning. ``` -------------------------------- ### Interact with a session using custom input actions Source: https://docs.rs/expectrl/0.8.0/expectrl/interact/index.html Demonstrates how to use the Lookup helper to define custom input triggers and manage state during an interactive session. ```rust use expectrl::{ interact::actions::lookup::Lookup, spawn, stream::stdin::Stdin, Regex }; #[derive(Debug)] enum Answer { Yes, No, Unrecognized, } let mut session = spawn("cat").expect("Can't spawn a session"); let mut input_action = Lookup::new(); let mut stdin = Stdin::open().unwrap(); let stdout = std::io::stdout(); let mut term = session.interact(&mut stdin, stdout).with_state(Answer::Unrecognized); term.set_input_action(move |mut ctx| { let m = input_action.on(ctx.buf, ctx.eof, "yes")?; if m.is_some() { *ctx.state = Answer::Yes; }; let m = input_action.on(ctx.buf, ctx.eof, "no")?; if m.is_some() { *ctx.state = Answer::No; }; Ok(false) }); term.spawn().expect("Failed to run an interact session"); let answer = term.into_state(); stdin.close().unwrap(); println!("It was said {:?}", answer); ``` -------------------------------- ### Interact with FTP session Source: https://docs.rs/expectrl/0.8.0/expectrl/interact/actions/lookup/struct.Lookup.html Demonstrates spawning an FTP session and using a lookup callback to detect successful authentication. ```rust 9fn main() -> Result<(), Error> { 10 let mut p = spawn("ftp bks4-speedtest-1.tele2.net")?; 11 12 let mut auth = false; 13 let mut login_lookup = Lookup::new(); 14 let mut stdin = Stdin::open()?; 15 16 p.interact(&mut stdin, stdout()) 17 .with_state(&mut auth) 18 .set_output_action(move |ctx| { 19 if login_lookup 20 .on(ctx.buf, ctx.eof, "Login successful")? 21 .is_some() 22 { 23 **ctx.state = true; 24 return Ok(true); 25 } 26 27 Ok(false) 28 }) 29 .spawn()?; 30 31 stdin.close()?; 32 33 if !auth { 34 println!("An authefication was not passed"); 35 return Ok(()); 36 } 37 38 p.expect("ftp>")?; 39 p.send_line("cd upload")?; 40 p.expect("successfully changed.")?; 41 p.send_line("pwd")?; 42 p.expect(Regex("[0-9]+ \"/upload\""))?; 43 p.send(ControlCode::EndOfTransmission)?; 44 p.expect("Goodbye.")?; 45 Ok(()) 46} ``` -------------------------------- ### Spawn a bash session and interact with jobs Source: https://docs.rs/expectrl/0.8.0/expectrl/repl/fn.spawn_bash.html Demonstrates spawning a bash session, sending commands, managing background/foreground jobs, and handling control codes. ```rust fn main() -> Result<(), Error> { let mut p = spawn_bash()?; p.send_line("ping 8.8.8.8")?; p.expect("bytes of data")?; p.send(ControlCode::try_from("^Z").unwrap())?; p.expect_prompt()?; // bash writes 'ping 8.8.8.8' to stdout again to state which job was put into background p.send_line("bg")?; p.expect("ping 8.8.8.8")?; p.expect_prompt()?; p.send_line("sleep 0.5")?; p.expect_prompt()?; // bash writes 'ping 8.8.8.8' to stdout again to state which job was put into foreground p.send_line("fg")?; p.expect("ping 8.8.8.8")?; p.send(ControlCode::try_from("^D").unwrap())?; p.expect("packet loss")?; Ok(()) } ``` -------------------------------- ### Rust Signal AsRef Implementation Source: https://docs.rs/expectrl/0.8.0/expectrl/process/unix/enum.Signal.html Implements the `AsRef` trait for the `Signal` enum, allowing conversion to a string slice reference. This provides a standard way to get the string representation of a signal. ```rust fn as_ref(&self) -> &str ``` -------------------------------- ### Execute commands and parse output in bash Source: https://docs.rs/expectrl/0.8.0/expectrl/repl/fn.spawn_bash.html Shows various interaction patterns including direct execution, regex-based output parsing, and continuous reading of command output. ```rust fn main() { let mut p = spawn_bash().unwrap(); // case 1: execute let hostname = p.execute("hostname").unwrap(); println!("Current hostname: {:?}", String::from_utf8_lossy(&hostname)); // case 2: wait until done, only extract a few infos p.send_line("wc /etc/passwd").unwrap(); // `expect` returns both string-before-match and match itself, discard first let found = p.expect(Regex("([0-9]+).*([0-9]+).*([0-9]+)")).unwrap(); let lines = String::from_utf8_lossy(&found[1]); let words = String::from_utf8_lossy(&found[2]); let chars = String::from_utf8_lossy(&found[3]); p.expect_prompt().unwrap(); // go sure `wc` is really done println!( "/etc/passwd has {} lines, {} words, {} chars", lines, words, chars, ); // case 3: read while program is still executing p.send_line("ping 8.8.8.8").unwrap(); // returns when it sees "bytes of data" in output for _ in 0..5 { // times out if one ping takes longer than 2s let duration = p.expect(Regex("[0-9. ]+ ms")).unwrap(); println!("Roundtrip time: {}", String::from_utf8_lossy(&duration[0])); } p.send(ControlCode::EOT).unwrap(); } ``` -------------------------------- ### Spawn a Session Source: https://docs.rs/expectrl/0.8.0/expectrl/session/type.OsSession.html Initializes a new session by spawning a command. ```rust use std::process::Command; use expectrl::Session; let p = Session::spawn(Command::new("cat")); ``` -------------------------------- ### Interact with complex callbacks Source: https://docs.rs/expectrl/0.8.0/expectrl/interact/actions/lookup/struct.Lookup.html Shows how to use both input and output actions with state tracking to monitor and respond to process output. ```rust 13fn main() { 14 let mut output_action = Lookup::new(); 15 let mut input_action = Lookup::new(); 16 let mut state = State::default(); 17 18 let mut session = spawn("python ./tests/source/ansi.py").expect("Can't spawn a session"); 19 20 let mut stdin = Stdin::open().unwrap(); 21 let stdout = std::io::stdout(); 22 23 let (is_alive, status) = { 24 let mut interact = session.interact(&mut stdin, stdout).with_state(&mut state); 25 interact 26 .set_output_action(move |ctx| { 27 let m = output_action.on(ctx.buf, ctx.eof, "Continue [y/n]:")?; 28 if m.is_some() { 29 ctx.state.wait_for_continue = Some(true); 30 }; 31 32 let m = output_action.on(ctx.buf, ctx.eof, Regex("status:\\s*.*\\w+.*\\r\\n"))?; 33 if m.is_some() { 34 ctx.state.stutus_verification_counter = 35 Some(ctx.state.stutus_verification_counter.map_or(1, |c| c + 1)); 36 output_action.clear(); 37 } 38 39 Ok(false) 40 }) 41 .set_input_action(move |ctx| { 42 let m = input_action.on(ctx.buf, ctx.eof, "y")?; 43 if m.is_some() { 44 if let Some(_a @ true) = ctx.state.wait_for_continue { 45 ctx.state.pressed_yes_on_continue = Some(true); 46 } 47 }; 48 49 let m = input_action.on(ctx.buf, ctx.eof, "n")?; 50 if m.is_some() { 51 if let Some(_a @ true) = ctx.state.wait_for_continue { 52 ctx.state.pressed_yes_on_continue = Some(false); 53 } 54 } 55 56 Ok(false) 57 }); 58 59 let is_alive = interact.spawn().expect("Failed to start interact"); 60 61 (is_alive, interact.get_status()) 62 }; 63 64 if !is_alive { 65 println!("The process was exited"); 66 #[cfg(unix)] 67 println!("Status={:?}", status); 68 } 69 70 stdin.close().unwrap(); 71 72 println!("RESULTS"); 73 println!( 74 "Number of time 'Y' was pressed = {}", 75 state.pressed_yes_on_continue.unwrap_or_default() 76 ); 77 println!( 78 "Status counter = {}", 79 state.stutus_verification_counter.unwrap_or_default() 80 ); 81} ``` -------------------------------- ### Interact with a shell using Stdin Source: https://docs.rs/expectrl/0.8.0/expectrl/stream/stdin/struct.Stdin.html Demonstrates opening a shell session, interacting with it via Stdin, and closing the input stream. ```rust fn main() { let mut sh = spawn(SHELL).expect("Error while spawning sh"); println!("Now you're in interacting mode"); println!("To return control back to main type CTRL-] combination"); let mut stdin = Stdin::open().expect("Failed to create stdin"); sh.interact(&mut stdin, stdout()) .spawn() .expect("Failed to start interact"); stdin.close().expect("Failed to close a stdin"); println!("Exiting"); } ``` -------------------------------- ### Session::spawn Source: https://docs.rs/expectrl/0.8.0/expectrl/session/index.html Spawns a new process and returns a Session instance to control it. ```APIDOC ## Session::spawn ### Description Spawns a process using a command and returns a Session instance for communication. ### Method Static Method ### Request Example ```rust use std::process::Command; use expectrl::Session; let mut p = Session::spawn(Command::new("cat")).unwrap(); ``` ``` -------------------------------- ### Interact with an FTP session using Stdin and state Source: https://docs.rs/expectrl/0.8.0/expectrl/stream/stdin/struct.Stdin.html Shows how to use Stdin within an interactive session that tracks state and performs output actions. ```rust fn main() -> Result<(), Error> { let mut p = spawn("ftp bks4-speedtest-1.tele2.net")?; let mut auth = false; let mut login_lookup = Lookup::new(); let mut stdin = Stdin::open()?; p.interact(&mut stdin, stdout()) .with_state(&mut auth) .set_output_action(move |ctx| { if login_lookup .on(ctx.buf, ctx.eof, "Login successful")? .is_some() { **ctx.state = true; return Ok(true); } Ok(false) }) .spawn()?; stdin.close()?; if !auth { println!("An authefication was not passed"); return Ok(()); } p.expect("ftp>")?; p.send_line("cd upload")?; p.expect("successfully changed.")?; p.send_line("pwd")?; p.expect(Regex("[0-9]+ \"/upload\""))?; p.send(ControlCode::EndOfTransmission)?; p.expect("Goodbye.")?; Ok(()) } ``` -------------------------------- ### Session::spawn (Unix) Source: https://docs.rs/expectrl/0.8.0/expectrl/session/struct.Session.html Spawns a session on a Unix-like platform process. ```APIDOC ## impl Session ### pub fn spawn(command: Command) -> Result #### Description Spawns a session on a platform process. #### Parameters * `command` (Command) - The command to execute. #### Returns * `Result` - A new Session instance on success, or an Error. #### Example ```rust use std::process::Command; use expectrl::Session; let p = Session::spawn(Command::new("cat")); ``` ``` -------------------------------- ### Function spawn Source: https://docs.rs/expectrl/0.8.0/expectrl/fn.spawn.html Spawns a new session by executing a command. It accepts a command string and returns an OsSession or an Error. ```APIDOC ## spawn ### Description Spawns a new session. It accepts a command and optional arguments as a string. It does not parse environment variables. ### Method Function Call ### Parameters #### Request Body - **cmd** (AsRef) - Required - The command to execute, including arguments. ### Response #### Success Response (Ok) - **OsSession** - The session object representing the spawned process. #### Error Response (Err) - **Error** - An error object if the process could not be spawned. ``` -------------------------------- ### Create a Lookup object Source: https://docs.rs/expectrl/0.8.0/expectrl/interact/actions/lookup/struct.Lookup.html Use `Lookup::new()` to create a new instance of the Lookup helper. This is typically done before setting up interaction actions. ```rust let mut login_lookup = Lookup::new(); ``` ```rust let mut output_action = Lookup::new(); ``` ```rust let mut input_action = Lookup::new(); ``` -------------------------------- ### Lookup::new Source: https://docs.rs/expectrl/0.8.0/expectrl/interact/actions/lookup/struct.Lookup.html Creates a new instance of the Lookup helper action. ```APIDOC ## Lookup::new ### Description Creates a new lookup object to be used within an InteractSession. ### Method Constructor ### Response - **Self** (Lookup) - A new instance of the Lookup struct. ``` -------------------------------- ### UnixProcess Module Source: https://docs.rs/expectrl/0.8.0/expectrl/process/unix/index.html Details the Unix implementation of crate::process::Process. ```APIDOC ## Module unix This module contains a Unix implementation of crate::process::Process. ### Structs #### PtyStream A IO stream (write/read) of UnixProcess. #### UnixProcess A Unix representation of a Process via PtyProcess ### Enums #### Signal Types of operating system signals #### WaitStatus Possible return values from `wait()` or `waitpid()`. ``` -------------------------------- ### Generic Blanket Implementations Source: https://docs.rs/expectrl/0.8.0/expectrl/stream/log/struct.LogStream.html Documentation for generic blanket implementations applicable to various types, including Any, Borrow, BorrowMut, From, Into, Receiver, TryFrom, and TryInto. ```APIDOC ## Generic Blanket Implementations ### `impl Any for T` **Where:** `T: 'static + ?Sized` #### `fn type_id(&self) -> TypeId` Gets the `TypeId` of `self`. ### `impl Borrow for T` **Where:** `T: ?Sized` #### `fn borrow(&self) -> &T` Immutably borrows from an owned value. ### `impl BorrowMut for T` **Where:** `T: ?Sized` #### `fn borrow_mut(&mut self) -> &mut T` Mutably borrows from an owned value. ### `impl From for T` #### `fn from(t: T) -> T` Returns the argument unchanged. ### `impl Into for T` **Where:** `U: From` #### `fn into(self) -> U` Calls `U::from(self)`. ### `impl Receiver for P` **Where:** `P: Deref + ?Sized`, `T: ?Sized` #### `type Target = T` *Nightly-only experimental API. (`arbitrary_self_types`)* The target type on which the method may be called. ### `impl TryFrom for T` **Where:** `U: Into` #### `type Error = Infallible` The type returned in the event of a conversion error. #### `fn try_from(value: U) -> Result>::Error>` Performs the conversion. ### `impl TryInto for T` **Where:** `U: TryFrom` #### `type Error = >::Error` The type returned in the event of a conversion error. #### `fn try_into(self) -> Result>::Error>` Performs the conversion. ``` -------------------------------- ### Automate FTP client interactions Source: https://docs.rs/expectrl/0.8.0/expectrl/fn.spawn.html Automates a sequence of commands for an FTP client, including login, changing directories, and retrieving information. ```rust 4fn main() -> Result<(), Error> { 5 let mut p = spawn("ftp bks4-speedtest-1.tele2.net")?; 6 p.expect(Regex("Name \(.*\):\?"))?; 7 p.send_line("anonymous")?; 8 p.expect("Password")?; 9 p.send_line("test")?; 10 p.expect("ftp>")?; 11 p.send_line("cd upload")?; 12 p.expect("successfully changed.")?; 13 p.send_line("pwd")?; 14 p.expect(Regex("[0-9]+ \"/upload\""))?; 15 p.send(ControlCode::EndOfTransmission)?; 16 p.expect("Goodbye.")?; 17 Ok(()) 18} ``` -------------------------------- ### UnixProcess Process Implementation - Spawn Command Source: https://docs.rs/expectrl/0.8.0/expectrl/session/type.OsProcess.html Spawns a new process by executing a given command. This method takes a command object and returns a Result containing the spawned process. ```rust type Command = Command; fn spawn_command(command: Self::Command) -> Result ``` -------------------------------- ### Session::new Source: https://docs.rs/expectrl/0.8.0/expectrl/session/struct.Session.html Creates a new session for a given process and stream. ```APIDOC ## impl Session ### pub fn new(process: P, stream: S) -> Result #### Description Creates a new session. #### Parameters * `process` (P) - The process handle. * `stream` (S) - The stream for communication. #### Returns * `Result` - A new Session instance on success, or an error. ``` -------------------------------- ### Interact with Callbacks for State Management Source: https://docs.rs/expectrl/0.8.0/expectrl/session/type.OsSession.html This snippet shows an advanced interaction with a Python script, using both output and input actions with callbacks to manage state. It demonstrates how to react to specific output patterns and control input based on prompts. ```rust fn main() { let mut output_action = Lookup::new(); let mut input_action = Lookup::new(); let mut state = State::default(); let mut session = spawn("python ./tests/source/ansi.py").expect("Can't spawn a session"); let mut stdin = Stdin::open().unwrap(); let stdout = std::io::stdout(); let (is_alive, status) = { let mut interact = session.interact(&mut stdin, stdout).with_state(&mut state); interact .set_output_action(move |ctx| { let m = output_action.on(ctx.buf, ctx.eof, "Continue [y/n]:")?; if m.is_some() { ctx.state.wait_for_continue = Some(true); }; let m = output_action.on(ctx.buf, ctx.eof, Regex("status:\s*.*\w+.*\r\n"))?; if m.is_some() { ctx.state.stutus_verification_counter = Some(ctx.state.stutus_verification_counter.map_or(1, |c| c + 1)); output_action.clear(); } Ok(false) }) .set_input_action(move |ctx| { let m = input_action.on(ctx.buf, ctx.eof, "y")?; if m.is_some() { if let Some(_a @ true) = ctx.state.wait_for_continue { ctx.state.pressed_yes_on_continue = Some(true); } }; let m = input_action.on(ctx.buf, ctx.eof, "n")?; if m.is_some() { if let Some(_a @ true) = ctx.state.wait_for_continue { ctx.state.pressed_yes_on_continue = Some(false); } } Ok(false) }); let is_alive = interact.spawn().expect("Failed to start interact"); (is_alive, interact.get_status()) }; if !is_alive { println!("The process was exited"); #[cfg(unix)] println!("Status={:?}", status); } stdin.close().unwrap(); println!("RESULTS"); println!( "Number of time 'Y' was pressed = {}", state.pressed_yes_on_continue.unwrap_or_default() ); println!( "Status counter = {}", state.stutus_verification_counter.unwrap_or_default() ); } ``` -------------------------------- ### Module: process Source: https://docs.rs/expectrl/0.8.0/expectrl/process/index.html Provides a platform-independent abstraction over an OS process. ```APIDOC ## Module: process ### Description This module contains a platform independent abstraction over an os process. ### Submodules - **unix**: This module contains a Unix implementation of crate::process::Process. ### Traits - **Healthcheck**: Represents a check by which we can determine if a spawned process is still alive. - **NonBlocking**: NonBlocking interface represents a std::io::Reader which can be turned in a non blocking mode so its read operations will return immediately. - **Process**: This trait represents a platform independent process which runs a program. - **Termios**: Terminal configuration trait, used for IO configuration. ``` -------------------------------- ### Log session output to stdout Source: https://docs.rs/expectrl/0.8.0/expectrl/fn.spawn.html Wraps an existing session to log all its input and output to stdout. Supports both synchronous and asynchronous operations. ```rust 6fn main() -> Result<(), Error> { 7 let p = spawn("cat")?; 8 let mut p = expectrl::session::log(p, std::io::stdout())?; 9 10 #[cfg(not(feature = "async"))] 11 { 12 p.send_line("Hello World")?; 13 p.expect("Hello World")?; 14 } 15 #[cfg(feature = "async")] 16 { 17 futures_lite::future::block_on(async { 18 p.send_line("Hello World").await?; 19 p.expect("Hello World").await 20 })?; 21 } 22 23 Ok(()) 24} ``` -------------------------------- ### ReplSession - Utility Methods Source: https://docs.rs/expectrl/0.8.0/expectrl/repl/struct.ReplSession.html Utility methods for the ReplSession. ```APIDOC ## POST /api/repl/is_matched ### Description Checks if a pattern is matched without consuming bytes from the stream. ### Method POST ### Endpoint /api/repl/is_matched ### Request Body - **needle** (Needle) - Required - The pattern to match. ### Response #### Success Response (200) - **matched** (boolean) - True if the pattern is matched, false otherwise. ``` -------------------------------- ### Interact with STDIN and STDOUT Source: https://docs.rs/expectrl/0.8.0/expectrl/index.html Connects a spawned process to the current process's standard input and output streams. ```rust use expectrl::{spawn, stream::stdin::Stdin}; use std::io::stdout; let mut sh = spawn("cat").expect("Failed to spawn a 'cat' process"); let mut stdin = Stdin::open().expect("Failed to create stdin"); sh.interact(&mut stdin, stdout()) .spawn() .expect("Failed to start interact session"); stdin.close().expect("Failed to close a stdin"); ``` -------------------------------- ### ReplSession Methods Source: https://docs.rs/expectrl/0.8.0/expectrl/repl/struct.ReplSession.html API documentation for the ReplSession struct methods used to manage interactive shell sessions. ```APIDOC ## ReplSession::new ### Description Creates a new ReplSession instance wrapping a spawned session. ### Parameters - **session** (S) - Required - A spawned session to wrap. - **prompt** (impl Into) - Required - The string identifying the command prompt. ## ReplSession::set_echo ### Description Configures the echo settings for the session. ### Parameters - **on** (bool) - Required - Whether echo is enabled. ## ReplSession::set_quit_command ### Description Sets the command to be executed when the session is dropped. ### Parameters - **cmd** (impl Into) - Required - The quit command string. ## ReplSession::expect_prompt ### Description Blocks execution until the configured prompt is detected in the session output. ### Returns - **Result<(), Error>** - Returns Ok if the prompt is found, otherwise an Error. ``` -------------------------------- ### InteractSession::spawn Source: https://docs.rs/expectrl/0.8.0/expectrl/interact/struct.InteractSession.html Executes the interactive session. ```APIDOC ## pub fn spawn(&mut self) -> Result ### Description Runs the session. This method initiates the interaction loop defined by the session configuration. ### Response - **Result** - Returns true if the session completed successfully, or an error if the process failed. ``` -------------------------------- ### spawn_bash Source: https://docs.rs/expectrl/0.8.0/expectrl/repl/index.html Spawns a new bash session for interactive command execution. ```APIDOC ## spawn_bash ### Description Spawns a bash session. This function initializes a new bash shell process that can be interacted with via the ReplSession interface. ### Method Function Call ### Endpoint expectrl::repl::spawn_bash ```