README.md in frontkick-0.5.2 vs README.md in frontkick-0.5.3
- old
+ new
@@ -1,78 +1,133 @@
# frontkick [![Build Status](https://secure.travis-ci.org/sonots/frontkick.png?branch=master)](http://travis-ci.org/sonots/frontkick) [![Dependency Status](https://gemnasium.com/sonots/frontkick.png)](https://gemnasium.com/sonots/frontkick)
-Frontkick is a gem to execute a command and obtain exit\_code, stdout, stderr simply.
+Frontkick is a gem to execute a command and obtain exit\_code, stdout, stderr simply.
## What is This For?
-Ruby's `Kernel.#system` method does not return STDOUT and STDERR.
+Ruby's `Kernel.#system` method does not return STDOUT and STDERR.
Ruby's back quote (``) returns STDOUT, but does not return STDERR.
-With frontkick, you can easily get the exit code, STDOUT, and STDERR.
+With frontkick, you can easily get the exit code, STDOUT, and STDERR.
## USAGE
- gem install frontkick
+```
+gem install frontkick
+```
### Basic Usage
- result = Frontkick.exec("echo *")
- puts result.successful? #=> true if exit_code is 0
- puts result.success? #=> alias to successful?, for compatibility with Process::Status
- puts result.stdout #=> stdout output of the command
- puts result.stderr #=> stderr output of the command
- puts result.exit_code #=> exit_code of the command
- puts result.status #=> alias to exit_code
- puts result.exitstatus #=> alias to exit_code, for compatibility with Process::Status
- puts result.duration #=> the time used to execute the command
+```ruby
+result = Frontkick.exec("echo *")
+puts result.successful? #=> true if exit_code is 0
+puts result.success? #=> alias to successful?, for compatibility with Process::Status
+puts result.stdout #=> stdout output of the command
+puts result.stderr #=> stderr output of the command
+puts result.exit_code #=> exit_code of the command
+puts result.status #=> alias to exit_code
+puts result.exitstatus #=> alias to exit_code, for compatibility with Process::Status
+puts result.duration #=> the time used to execute the command
+```
-### Escape Command
+### No Shell
- result = Frontkick.exec(["echo", "*"]) #=> echo the asterisk character
+**String argument**
+When the first argument is a String, the command is executed via shell if the command string includes meta characters of shell such as:
+
+```
+* ? {} [] <> () ~ & | \ $ ; ' ` " \n
+```
+
+otherwise, the command is not executed via shell.
+
+```ruby
+result = Frontkick.exec("echo foo") # no shell
+result = Frontkick.exec("echo *") # with shell
+```
+
+The process tree for the latter (with shell) will be like:
+
+```
+ruby
+└─ sh -c
+ └── echo *
+```
+
+**Array argument**
+
+When the first argument is an Array, The command is not executed via a shell.
+Note that shell wildcards are not available with this way.
+
+```ruby
+result = Frontkick.exec(["echo", "*"]) #=> echo the asterisk character
+```
+
+The process tree will be like:
+
+```
+ruby
+└─ echo
+```
+
### Dry Run Option
- result = Frontkick.exec(["echo", "*"], :dry_run => true)
- puts result.stdout #=> echo \*
+```ruby
+result = Frontkick.exec(["echo", "*"], :dry_run => true)
+puts result.stdout #=> echo \*
+```
### Timeout Option
- Frontkick.exec("sleep 2 && ls /hoge", :timeout => 1) # raises Frontkick::Timeout
+```ruby
+Frontkick.exec("sleep 2 && ls /hoge", :timeout => 1) # raises Frontkick::Timeout
+```
not to kill timeouted process
- Frontkick.exec("sleep 2 && ls /hoge", :timeout => 1, :timeout_kill => false) # raises Frontkick::Timeout
+```ruby
+Frontkick.exec("sleep 2 && ls /hoge", :timeout => 1, :timeout_kill => false) # raises Frontkick::Timeout
+```
### Exclusive Option
Prohibit another process to run a command concurrently
- Frontkick.exec("sleep 2 && ls /hoge", :exclusive => "/tmp/frontkick.lock") # raises Fontkick::Locked if locked
+```ruby
+Frontkick.exec("sleep 2 && ls /hoge", :exclusive => "/tmp/frontkick.lock") # raises Fontkick::Locked if locked
+```
If you prefer to be blocked:
- Frontkick.exec("sleep 2 && ls /hoge", :exclusive => "/tmp/frontkick.lock", :exclusive_blocking => true)
+```ruby
+Frontkick.exec("sleep 2 && ls /hoge", :exclusive => "/tmp/frontkick.lock", :exclusive_blocking => true)
+```
### Redirect Options (:out and :err)
- Frontkick.exec(["ls /something_not_found"], :out => 'stdout.txt', :err => 'stderr.txt')
+```ruby
+Frontkick.exec(["ls /something_not_found"], :out => 'stdout.txt', :err => 'stderr.txt')
+```
This redirects STDOUT and STDERR into files. In this case, result.stdout, and result.stderr are the given filename.
- out = File.open('stdout.txt', 'w').tap {|fp| fp.sync = true }
- err = File.open('stderr.txt', 'w').tap {|fp| fp.sync = true }
- Frontkick.exec(["ls /something_not_found"], :out => out, :err => err)
+```ruby
+out = File.open('stdout.txt', 'w').tap {|fp| fp.sync = true }
+err = File.open('stderr.txt', 'w').tap {|fp| fp.sync = true }
+Frontkick.exec(["ls /something_not_found"], :out => out, :err => err)
+```
You can also give IO objects. In this case, result.stdout, and result.stderr are the given IO objects.
### Popen3 Options (such as :chdir)
Other options such as :chdir are treated as options of `Open3.#popen3`.
### Kill Child Process
-Sending a signal to a kicked child process is fine because a frontkick process can finish.
-But, sending a signal to a frontkick process is not fine because a child process would become an orphan process.
+Although sending a signal to a kicked child process directly causes no problem (frontkick process can take care of it),
+sending a signal to a frontkick process may cause a problem that a child process becomes an orphan process.
To kill your frontkick process with its child process correctly, send a signal to their **process group** as
kill -TERM -{PGID}