Pane.send_line
Send literal text followed by Enter as one dispatch.
Source and package
- Qualified name
-
libtmux::pane:: Pane:: send _line - Module
- pane
- Declared in
Pane- Package
- libtmux
- Source
- crates/libtmux/src/pane.rs
-
Description#
The text is sensitive and stays out of diagnostics.
Errors
Returns an error when tmux refuses the line.
Cancel safety
The effect may or may not have happened, but never half of it: the text and its Enter travel as one
send-keys, so a dropped future cannot leave a line typed and not submitted. A retry can type the line twice.Examples#
Capture complete output lines. Submit a shell command atomically and wait for whole output lines within a deadline. Use Rust 1.85 or newer with Cargo, and tmux 3.3a or newer, on a Unix system. In an empty directory, create a project and add the published crates:
Terminal window $ cargo init --name libtmux-api-example &&cargo add libtmux@0.1.2 tempfile@3.20 &&cargo add tokio@1.40 --features macros,rt,timeReplace
src/main.rswith this complete program. It owns a private tmux socket, applies a ten-second task deadline, and reports both task and cleanup errors.Server::kill()stops its daemon;Server::shutdown()closes its client executor. Successful cleanup removes the temporary directory even when the task fails. View source//! Capture complete output lines after submitting a shell command.use std::error::Error;use std::time::Duration;use libtmux::{NewSessionOptions, PaneWait, Server};type ExampleError = Box<dyn Error>;async fn demonstrate(server: &Server) -> Result<(), ExampleError> {let session = server.new_session(NewSessionOptions::new("capture").command("env ENV=/dev/null PS1='api-ready> ' sh"),).await?;let panes = session.panes().await?;let pane = panes.first().ok_or("session has no pane")?;if pane.wait_for_text("api-ready>", Duration::from_secs(5)).await?!= PaneWait::Arrived{return Err("shell prompt did not become ready".into());}pane.send_line("printf '\\nfirst line\\nsecond line\\n'").await?;loop {let lines = pane.capture().await?;if lines.iter().any(|line| line.as_bytes() == b"first line")&& lines.iter().any(|line| line.as_bytes() == b"second line"){break;}tokio::time::sleep(Duration::from_millis(20)).await;}println!("capture: first line, second line");Ok(())}#[tokio::main(flavor = "current_thread")]async fn main() -> Result<(), ExampleError> {let root = std::path::Path::new("/tmp/libtmux-rs-dev");std::fs::create_dir_all(root)?;let directory = tempfile::Builder::new().prefix("api-capture-").tempdir_in(root)?;std::fs::write(directory.path().join("owner"),std::process::id().to_string(),)?;let server = Server::builder().socket_path(directory.path().join("tmux.sock")).config_file("/dev/null").default_timeout(Duration::from_secs(5)).build()?;let outcome = tokio::time::timeout(Duration::from_secs(10), demonstrate(&server)).await;// Stop the owned daemon before closing the client executor.let killed = server.kill().await;let closed = server.shutdown().await;let cleanup_failed = killed.is_err() || closed.is_err();let mut failures = Vec::new();match outcome {Ok(Ok(())) => {}Ok(Err(error)) => failures.push(format!("example failed: {error}")),Err(error) => failures.push(format!("example deadline: {error}")),}if let Err(error) = killed {failures.push(format!("daemon cleanup: {error}"));}if let Err(error) = closed {failures.push(format!("executor cleanup: {error}"));}if cleanup_failed {let retained = directory.keep();failures.push(format!("inspect retained directory {}", retained.display()));} else if let Err(error) = directory.close() {failures.push(format!("directory cleanup: {error}"));}if failures.is_empty() {Ok(())} else {Err(failures.join("; ").into())}}Run the consumer. Success exits with status 0; setup, operation, deadline or cleanup failures exit unsuccessfully and print diagnostics to stderr:
Terminal window $ cargo run --quietExpected output:
capture: first line, second line
tmux command#
The tmux commands behind send_line.
tmux C API#
The C declarations in tmux that implement these commands.
Guides#
Pages that discuss send_line.
- Guides
- Topics