All Projects → philippkeller → Rexpect

philippkeller / Rexpect

Licence: mit
Rust port of pexpect

Programming Languages

rust
11053 projects

Labels

Projects that are alternatives of or similar to Rexpect

Bin
~/bin
Stars: ✭ 93 (-15.45%)
Mutual labels:  unix
Unix Permissions
Swiss Army knife for Unix permissions
Stars: ✭ 106 (-3.64%)
Mutual labels:  unix
Passhole
A secure hole for your passwords (KeePass CLI)
Stars: ✭ 108 (-1.82%)
Mutual labels:  unix
Xnotify
read notifications from stdin and pop them up on the screen
Stars: ✭ 97 (-11.82%)
Mutual labels:  unix
Covise
Collaborative Visualization and Simulation Environment, OpenCOVER and OddLOT
Stars: ✭ 101 (-8.18%)
Mutual labels:  unix
Domain Check 2
Domain Expiration Check Shell Script Forked and Maintained by nixCraft
Stars: ✭ 107 (-2.73%)
Mutual labels:  unix
Cli Boot.camp
💻 command-line bootcamp adventure in your browser
Stars: ✭ 88 (-20%)
Mutual labels:  unix
Makeself
A self-extracting archiving tool for Unix systems, in 100% shell script.
Stars: ✭ 1,582 (+1338.18%)
Mutual labels:  unix
Minishell
As beautiful as a shell
Stars: ✭ 105 (-4.55%)
Mutual labels:  unix
Fh
file history with ed(1), diff(1), awk(1), sed(1) and sh(1)
Stars: ✭ 108 (-1.82%)
Mutual labels:  unix
Dte
A small, configurable console text editor (moved to https://gitlab.com/craigbarnes/dte)
Stars: ✭ 98 (-10.91%)
Mutual labels:  unix
Screen Recorder Ffmpeg Cpp
*Multimedia project* A screen recording application to capture your desktop and store in a video format. Click here to watch the demo
Stars: ✭ 98 (-10.91%)
Mutual labels:  unix
Serenity
SerenityOS is a love letter to '90s user interfaces with a custom Unix-like core. It flatters with sincerity by stealing beautiful ideas from various other systems.
Stars: ✭ 16,842 (+15210.91%)
Mutual labels:  unix
Ldap4net
OpenLdap port for DotNet Core (Linux\OSX\Windows)
Stars: ✭ 93 (-15.45%)
Mutual labels:  unix
Walk
A fast, general purpose, graph based build and task execution utility.
Stars: ✭ 108 (-1.82%)
Mutual labels:  unix
Irccat
cat to IRC
Stars: ✭ 91 (-17.27%)
Mutual labels:  unix
Punk.py
unix SSH post-exploitation 1337 tool
Stars: ✭ 107 (-2.73%)
Mutual labels:  unix
Pwd.sh
GPG symmetric password manager
Stars: ✭ 1,468 (+1234.55%)
Mutual labels:  unix
Dotfiles
▒ rice ░░ custom linux config files
Stars: ✭ 1,514 (+1276.36%)
Mutual labels:  unix
Fzf
🌸 A command-line fuzzy finder
Stars: ✭ 40,965 (+37140.91%)
Mutual labels:  unix

rexpect

Build Status crates.io Released API docs Master API docs

Spawn, control, and respond to expected patterns of child applications and processes, enabling the automation of interactions and testing. Components include:

  • session: start a new process and interact with it; primary module of rexpect.
  • reader: non-blocking reader, which supports waiting for strings, regex, and EOF.
  • process: spawn a process in a pty.

The goal is to offer a similar set of functionality as pexpect.

Maintainers wanted

I have created rexpect as a project to learn rust and linux. But now due to some reasons I haven't used Rust in the past 2 years, so I can't keep up with the latest features/crate dependencies

It has become hard now to judge pull requests. If you would be willing to either take over this repo entirely or join in as a maintainer to help evaluate PR please contact me.

Examples

For more examples, check the examples directory.

Basic usage

Add this to your Cargo.toml

[dependencies]
rexpect = "0.4"

Simple example for interacting via ftp:

extern crate rexpect;

use rexpect::spawn;
use rexpect::errors::*;

fn do_ftp() -> Result<()> {
    let mut p = spawn("ftp speedtest.tele2.net", Some(30_000))?;
    p.exp_regex("Name \\(.*\\):")?;
    p.send_line("anonymous")?;
    p.exp_string("Password")?;
    p.send_line("test")?;
    p.exp_string("ftp>")?;
    p.send_line("cd upload")?;
    p.exp_string("successfully changed.\r\nftp>")?;
    p.send_line("pwd")?;
    p.exp_regex("[0-9]+ \"/upload\"")?;
    p.send_line("exit")?;
    p.exp_eof()?;
    Ok(())
}


fn main() {
    do_ftp().unwrap_or_else(|e| panic!("ftp job failed with {}", e));
}

Example with bash and reading from programs

extern crate rexpect;
use rexpect::spawn_bash;
use rexpect::errors::*;


fn do_bash() -> Result<()> {
    let mut p = spawn_bash(Some(2000))?;
    
    // case 1: wait until program is done
    p.send_line("hostname")?;
    let hostname = p.read_line()?;
    p.wait_for_prompt()?; // go sure `hostname` is really done
    println!("Current hostname: {}", hostname);

    // case 2: wait until done, only extract a few infos
    p.send_line("wc /etc/passwd")?;
    // `exp_regex` returns both string-before-match and match itself, discard first
    let (_, lines) = p.exp_regex("[0-9]+")?;
    let (_, words) = p.exp_regex("[0-9]+")?;
    let (_, bytes) = p.exp_regex("[0-9]+")?;
    p.wait_for_prompt()?; // go sure `wc` is really done
    println!("/etc/passwd has {} lines, {} words, {} chars", lines, words, bytes);

    // case 3: read while program is still executing
    p.execute("ping 8.8.8.8", "bytes of data")?; // 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.exp_regex("[0-9. ]+ ms")?;
        println!("Roundtrip time: {}", duration);
    }
    p.send_control('c')?;
    Ok(())
}

fn main() {
    do_bash().unwrap_or_else(|e| panic!("bash job failed with {}", e));
}

Example with bash and job control

One frequent bitfall with sending ctrl-c and friends is that you need to somehow ensure that the program has fully loaded, otherwise the ctrl-* goes into nirvana. There are two functions to ensure that:

  • execute where you need to provide a match string which is present on stdout/stderr when the program is ready
  • wait_for_prompt which waits until the prompt is shown again
extern crate rexpect;
use rexpect::spawn_bash;
use rexpect::errors::*;


fn do_bash_jobcontrol() -> Result<()> {
    let mut p = spawn_bash(Some(1000))?;
    p.execute("ping 8.8.8.8", "bytes of data")?;
    p.send_control('z')?;
    p.wait_for_prompt()?;
    // bash writes 'ping 8.8.8.8' to stdout again to state which job was put into background
    p.execute("bg", "ping 8.8.8.8")?;
    p.wait_for_prompt()?;
    p.send_line("sleep 0.5")?;
    p.wait_for_prompt()?;
    // bash writes 'ping 8.8.8.8' to stdout again to state which job was put into foreground
    p.execute("fg", "ping 8.8.8.8")?;
    p.send_control('c')?;
    p.exp_string("packet loss")?;
    Ok(())
}

fn main() {
    do_bash_jobcontrol().unwrap_or_else(|e| panic!("bash with job control failed with {}", e));
}

Project Status

Rexpect covers more or less the features of pexpect. If you miss anything I'm happy to receive PRs or also Issue requests of course.

The tests cover most of the aspects and it should run out of the box for rust stable, beta and nightly on both Linux or Mac.

Design decisions

  • use error handling of error-chain
  • use nix (and avoid libc wherever possible) to keep the code safe and clean
  • sadly, expect is used in rust too prominently to unwrap Options and Results, use exp_* instead

Licensed under MIT License

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].