run_shell 0.1.13

shell script written in rust
Documentation
# run_shell - shell script written in rust.

run_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

```rust
extern crate run_shell;
use run_shell::*;

// Run command by cmd! macro
cmd!("echo Hello rust run_shell!").run().unwrap();

// Contain white space or non-alphabetical characters
cmd!("echo \"%$#\"").run().unwrap();

// Pass an argument
let name = "run_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.

```rust
extern crate run_shell;
use run_shell::*;

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.

```rust
extern crate run_shell;
use run_shell::*;

assert_eq!(cmd!("echo OK").stdout_utf8().unwrap(), "OK\n");
```

## Spawn

ShellCommand has `spawn()` method which runs the command asynchronously and
returns `ShellChild`.

```rust
extern crate run_shell;
use run_shell::*;
extern crate libc;

// Wait
let child = cmd!("sleep 2").spawn().unwrap();
child.wait().unwrap();

// Signal
let child = cmd!("sleep 2").spawn().unwrap();
let result = child.wait();
assert!(result.status().is_ok(), "Still able to obtain status");
```

## Thread

If you would like to run a sequence of commands asynchronously, `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.

```rust
extern crate run_shell;
use run_shell::*;
extern crate libc;

let handle = run_shell::spawn(|| -> ShellResult {
  cmd!("sleep 3").run()
});
let result = handle.join().unwrap();
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.

```rust
extern crate run_shell;
use 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.

```rust
extern crate run_shell;
use run_shell::*;
use std::process::Stdio;
use std::io::Read;

 // Access std::process::Command.
    let mut shell_command = cmd!("echo OK");
    {
        let 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 child = &mut lock.as_mut().unwrap().child;
        let mut str = String::new();
        child
            .stdout
            .as_mut()
            .unwrap()
            .read_to_string(&mut str)
            .unwrap();
    }
    shell_child.wait().unwrap();
```