run_shell/
lib.rs

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