1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190
//! # Rust shell - shell script written in rust.
//!
//! This is not an officially supported Google product
//!
//! Rust shell is a helper library for std::process::Command to write shell
//! script like tasks in rust. The library only works with unix-like operation
//! systems.
//!
//! ## Run command
//!
//! `run!` macro creates a ShellCommand instance which you can run by `run()`
//! method.
//!
//! ```
//! #[macro_use] extern crate run_shell;
//!
//! # fn main() {
//! // Run command by cmd! macro
//! cmd!("echo Hello rust shell!").run().unwrap();
//!
//! // Contain white space or non-alphabetical characters
//! cmd!("echo \"%$#\"").run().unwrap();
//!
//! // Pass an argument
//! let name = "shell";
//! cmd!("echo Hello rust {}!", name).run().unwrap();
//!
//! // Extract environment variable
//! cmd!("echo HOME is $HOME").run().unwrap();
//! # }
//! ```
//! ## ShellResult
//!
//! The return value of `ShellCommand#run()` is `ShellResult` which is `Ok(_)`
//! only when the command successfully runs and its execution code is 0, so you
//! can use `?` operator to check if the command successfully exits or not.
//!
//! ```
//! extern crate run_shell;
//! use run_shell::*;
//!
//! # fn main() {
//! # shell_function().unwrap();
//! # }
//! fn shell_function() -> ShellResult {
//! cmd!("echo Command A").run()?;
//! cmd!("echo Command B").run()?;
//! run_shell::ok()
//! }
//! ```
//!
//! ## Output string
//!
//! ShellCommand has a shorthand to obtain stdout as UTF8 string.
//!
//! ```
//! #[macro_use] extern crate run_shell;
//!
//! # fn main() {
//! assert_eq!(cmd!("echo OK").stdout_utf8().unwrap(), "OK\n");
//! # }
//! ```
//!
//! ## Spawn
//!
//! ShellCommand has `spawn()` method which runs the command asynchronously and
//! returns `ShellChild`.
//!
//! ```
//! #[macro_use] extern crate run_shell;
//! extern crate libc;
//! use run_shell::ShellResultExt;
//!
//! # fn main() {
//! // Wait
//! let child = cmd!("sleep 2").spawn().unwrap();
//! child.wait().unwrap();
//!
//! // Signal
//! let child = cmd!("sleep 2").spawn().unwrap();
//! child.signal(libc::SIGINT);
//! let result = child.wait();
//! assert!(result.is_err(), "Should be error as it exits with a signal");
//! assert!(result.status().is_ok(), "Still able to obtain status");
//! # }
//! ```
//!
//! ## Thread
//!
//! If you would like to run a sequence of commands asynchronously,
//! `run_shell::spawn` creates a thread as well as `std::thread::spawn` but it
//! returns `ShellHandle` wrapping `std::thread::JoinHandle`.
//!
//! `ShellHandle#signal()` is used to send a signal to processes running on the
//! thread. It also stops launching a new process by `ShellComamnd::run()` on
//! that thread.
//!
//! ```
//! #[macro_use] extern crate run_shell;
//! extern crate libc;
//! use run_shell::ShellResult;
//! use run_shell::ShellResultExt;
//!
//! # fn main() {
//! let handle = run_shell::spawn(|| -> ShellResult {
//! cmd!("sleep 3").run()
//! });
//! handle.signal(libc::SIGINT);
//! let result = handle.join().unwrap();
//! assert!(result.is_err(), "Should be error as it exits with a signal");
//! assert!(result.status().is_ok(), "Still able to obtain status");
//! # }
//! ```
//!
//! ## Signal handling
//!
//! `trap_signal_and_wait_children()` starts watching SIGINT and SIGTERM, and
//! waits all child processes before exiting the process when receiving these
//! signals. The function needs to be called before launching any new thread.
//!
//! ```
//! extern crate run_shell;
//! run_shell::trap_signal_and_wait_children().unwrap();
//! ```
//!
//! ## Access underlaying objects
//!
//! `ShellComamnd` wraps `std::process::Command` and `ShellChild` wraps
//! `std::process::Child`. Both underlaying objects are accessible via public
//! fields.
//!
//! ```
//! #[macro_use] extern crate run_shell;
//! use std::process::Stdio;
//! use std::io::Read;
//!
//! # fn main() {
//! // Access std::process::Command.
//! let mut shell_command = cmd!("echo OK");
//! {
//! let mut command = &mut shell_command.command;
//! command.stdout(Stdio::piped());
//! }
//!
//! // Access std::process::Child.
//! let shell_child = shell_command.spawn().unwrap();
//! {
//! let mut lock = shell_child.0.write().unwrap();
//! let mut child = &mut lock.as_mut().unwrap().child;
//! let mut str = String::new();
//! child.stdout.as_mut().unwrap().read_to_string(&mut str);
//! }
//! shell_child.wait().unwrap();
//! # }
//! ```
//!
//! ## License
//! Apatch 2 License
#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate log;
#[macro_use]
extern crate nom;
extern crate env_logger;
extern crate errno;
extern crate libc;
extern crate regex;
#[macro_use]
mod command;
mod local_shell;
mod process_manager;
mod result;
mod shell_child;
mod shell_command;
pub use command::new_command;
pub use local_shell::spawn;
pub use local_shell::ShellHandle;
pub use process_manager::trap_signal_and_wait_children;
pub use result::ok;
pub use result::ShellError;
pub use result::ShellResult;
pub use result::ShellResultExt;
pub use shell_child::ShellChild;
pub use shell_child::ShellChildArc;
pub use shell_child::ShellChildCore;
pub use shell_command::ShellCommand;