{"id":13438618,"url":"https://github.com/rust-cli/rexpect","last_synced_at":"2025-10-24T01:21:01.392Z","repository":{"id":21509934,"uuid":"93129958","full_name":"rust-cli/rexpect","owner":"rust-cli","description":".github/workflows/ci.yml","archived":false,"fork":false,"pushed_at":"2025-05-01T17:48:22.000Z","size":384,"stargazers_count":348,"open_issues_count":33,"forks_count":62,"subscribers_count":10,"default_branch":"main","last_synced_at":"2025-05-01T18:03:38.388Z","etag":null,"topics":["pexpect","processes","pty","unix"],"latest_commit_sha":null,"homepage":"https://docs.rs/rexpect","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rust-cli.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2017-06-02T05:24:21.000Z","updated_at":"2025-05-01T17:48:25.000Z","dependencies_parsed_at":"2025-04-14T16:57:29.003Z","dependency_job_id":"208ac2f3-1cad-4eb4-9d58-46b663e6743b","html_url":"https://github.com/rust-cli/rexpect","commit_stats":{"total_commits":274,"total_committers":22,"mean_commits":"12.454545454545455","dds":0.4854014598540146,"last_synced_commit":"52edda700d39edabc1a7abcfa2d45ddb14e629c0"},"previous_names":["philippkeller/rexpect"],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rust-cli%2Frexpect","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rust-cli%2Frexpect/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rust-cli%2Frexpect/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rust-cli%2Frexpect/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rust-cli","download_url":"https://codeload.github.com/rust-cli/rexpect/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254328384,"owners_count":22052632,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["pexpect","processes","pty","unix"],"created_at":"2024-07-31T03:01:06.888Z","updated_at":"2025-10-24T01:20:56.339Z","avatar_url":"https://github.com/rust-cli.png","language":"Rust","readme":"# rexpect\n\n[![Documentation](https://img.shields.io/badge/docs-master-blue.svg)][Documentation]\n![License](https://img.shields.io/crates/l/rexpect.svg)\n[![Crates Status](https://img.shields.io/crates/v/rexpect.svg)][Crates.io]\n\nSpawn, control, and respond to expected patterns of child applications and\nprocesses, enabling the automation of interactions and testing. Components\ninclude:\n\n- **session**: start a new process and interact with it; primary module of\n  rexpect.\n- **reader**: non-blocking reader, which supports waiting for strings, regex,\n  and EOF.\n- **process**: spawn a process in a pty.\n\nThe goal is to offer a similar set of functionality as\n[pexpect](https://pexpect.readthedocs.io/en/stable/overview.html).\n\n## Examples\n\n[For more examples, check the examples directory.](https://github.com/philippkeller/rexpect/tree/master/examples)\n\n### Basic usage\n\nSimple example for interacting via ftp:\n\n```rust,no_run\nuse rexpect::spawn;\nuse rexpect::error::*;\n\nfn do_ftp() -\u003e Result\u003c(), Error\u003e {\n    let mut p = spawn(\"ftp speedtest.tele2.net\", Some(30_000))?;\n    p.exp_regex(\"Name \\\\(.*\\\\):\")?;\n    p.send_line(\"anonymous\")?;\n    p.exp_string(\"Password\")?;\n    p.send_line(\"test\")?;\n    p.exp_string(\"ftp\u003e\")?;\n    p.send_line(\"cd upload\")?;\n    p.exp_string(\"successfully changed.\\r\\nftp\u003e\")?;\n    p.send_line(\"pwd\")?;\n    p.exp_regex(\"[0-9]+ \\\"/upload\\\"\")?;\n    p.send_line(\"exit\")?;\n    p.exp_eof()?;\n    Ok(())\n}\n\nfn main() {\n    do_ftp().unwrap_or_else(|e| panic!(\"ftp job failed with {}\", e));\n}\n```\n\n### Example with bash and reading from programs\n\n```rust,no_run\nuse rexpect::spawn_bash;\nuse rexpect::error::*;\n\nfn do_bash() -\u003e Result\u003c(), Error\u003e {\n    let mut p = spawn_bash(Some(2000))?;\n\n    // case 1: wait until program is done\n    p.send_line(\"hostname\")?;\n    let hostname = p.read_line()?;\n    p.wait_for_prompt()?; // go sure `hostname` is really done\n    println!(\"Current hostname: {}\", hostname);\n\n    // case 2: wait until done, only extract a few infos\n    p.send_line(\"wc /etc/passwd\")?;\n    // `exp_regex` returns both string-before-match and match itself, discard first\n    let (_, lines) = p.exp_regex(\"[0-9]+\")?;\n    let (_, words) = p.exp_regex(\"[0-9]+\")?;\n    let (_, bytes) = p.exp_regex(\"[0-9]+\")?;\n    p.wait_for_prompt()?; // go sure `wc` is really done\n    println!(\"/etc/passwd has {} lines, {} words, {} chars\", lines, words, bytes);\n\n    // case 3: read while program is still executing\n    p.execute(\"ping 8.8.8.8\", \"bytes of data\")?; // returns when it sees \"bytes of data\" in output\n    for _ in 0..5 {\n        // times out if one ping takes longer than 2s\n        let (_, duration) = p.exp_regex(\"[0-9. ]+ ms\")?;\n        println!(\"Roundtrip time: {}\", duration);\n    }\n    p.send_control('c')?;\n    Ok(())\n}\n\nfn main() {\n    do_bash().unwrap_or_else(|e| panic!(\"bash job failed with {}\", e));\n}\n```\n\n### Example with bash and job control\n\nOne frequent bitfall with sending ctrl-c and friends is that you need\nto somehow ensure that the program has fully loaded, otherwise the ctrl-*\ngoes into nirvana. There are two functions to ensure that:\n\n- `execute` where you need to provide a match string which is present\n  on stdout/stderr when the program is ready\n- `wait_for_prompt` which waits until the prompt is shown again\n\n\n\n```rust,no_run\nuse rexpect::spawn_bash;\nuse rexpect::error::*;\n\nfn do_bash_jobcontrol() -\u003e Result\u003c(), Error\u003e {\n    let mut p = spawn_bash(Some(1000))?;\n    p.execute(\"ping 8.8.8.8\", \"bytes of data\")?;\n    p.send_control('z')?;\n    p.wait_for_prompt()?;\n    // bash writes 'ping 8.8.8.8' to stdout again to state which job was put into background\n    p.execute(\"bg\", \"ping 8.8.8.8\")?;\n    p.wait_for_prompt()?;\n    p.send_line(\"sleep 0.5\")?;\n    p.wait_for_prompt()?;\n    // bash writes 'ping 8.8.8.8' to stdout again to state which job was put into foreground\n    p.execute(\"fg\", \"ping 8.8.8.8\")?;\n    p.send_control('c')?;\n    p.exp_string(\"packet loss\")?;\n    Ok(())\n}\n\nfn main() {\n    do_bash_jobcontrol().unwrap_or_else(|e| panic!(\"bash with job control failed with {}\", e));\n}\n\n```\n\n## License\n\nLicensed under either of\n\n* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or \u003chttp://www.apache.org/licenses/LICENSE-2.0\u003e)\n* MIT license ([LICENSE-MIT](LICENSE-MIT) or \u003chttp://opensource.org/licenses/MIT\u003e)\n\nat your option.\n\n### Contribution\n\nUnless you explicitly state otherwise, any contribution intentionally\nsubmitted for inclusion in the work by you, as defined in the Apache-2.0\nlicense, shall be dual licensed as above, without any additional terms or\nconditions.\n\n\n[Crates.io]: https://crates.io/crates/rexpect\n[Documentation]: https://docs.rs/rexpect\n","funding_links":[],"categories":["Libraries","Rust","库 Libraries","unix","Building"],"sub_categories":["Command-line","命令行 Command-line","Workflows"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frust-cli%2Frexpect","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frust-cli%2Frexpect","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frust-cli%2Frexpect/lists"}