command_exec 0.1.3 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +6 -2
- data/Gemfile.lock +42 -18
- data/README.md +707 -72
- data/RELEASE_NOTES.md +62 -0
- data/Rakefile +40 -9
- data/TODO.md +8 -2
- data/command_exec.gemspec +3 -2
- data/gemfiles/Gemfile.default +28 -0
- data/gemfiles/Gemfile.travis +16 -0
- data/gemfiles/Gemfile.travis.lock +48 -0
- data/lib/command_exec.rb +22 -2
- data/lib/command_exec/command.rb +307 -157
- data/lib/command_exec/exceptions.rb +16 -6
- data/lib/command_exec/field_helper.rb +263 -0
- data/lib/command_exec/formatter/array.rb +158 -0
- data/lib/command_exec/formatter/hash.rb +78 -0
- data/lib/command_exec/formatter/json.rb +22 -0
- data/lib/command_exec/formatter/string.rb +22 -0
- data/lib/command_exec/formatter/xml.rb +22 -0
- data/lib/command_exec/formatter/yaml.rb +22 -0
- data/lib/command_exec/logger.rb +9 -0
- data/lib/command_exec/process.rb +294 -0
- data/lib/command_exec/spec_helper_module.rb +52 -0
- data/lib/command_exec/version.rb +1 -1
- data/script/console +8 -0
- data/spec/command/command_spec.rb +413 -117
- data/spec/command/test_data/echo_test +3 -0
- data/spec/command/test_data/exit_status_test +2 -0
- data/spec/command/test_data/log_file_test +3 -0
- data/spec/command/test_data/logger_test +2 -0
- data/spec/command/test_data/not_raise_error_test +4 -0
- data/spec/command/test_data/not_throw_error_test +4 -0
- data/spec/command/test_data/output_test +6 -0
- data/spec/command/test_data/raise_error_test +6 -0
- data/spec/command/test_data/runner_open3_test +4 -0
- data/spec/command/test_data/runner_system_test +4 -0
- data/spec/command/test_data/stderr_test +4 -0
- data/spec/command/test_data/stdout_multiple_lines_test +4 -0
- data/spec/command/test_data/stdout_test +4 -0
- data/spec/command/test_data/throw_error_test +6 -0
- data/spec/command/test_data/true_test +2 -0
- data/spec/formatter/array_spec.rb +215 -0
- data/spec/formatter/hash_spec.rb +117 -0
- data/spec/formatter/json_spec.rb +21 -0
- data/spec/formatter/xml_spec.rb +33 -0
- data/spec/formatter/yaml_spec.rb +21 -0
- data/spec/process/process_spec.rb +329 -0
- data/spec/spec_helper.rb +15 -4
- metadata +79 -5
data/Gemfile
CHANGED
@@ -1,12 +1,11 @@
|
|
1
1
|
source :rubygems
|
2
2
|
|
3
3
|
# Specify your gem's dependencies in workplace-letter_generator.gemspec
|
4
|
-
gemspec
|
4
|
+
gemspec
|
5
5
|
|
6
6
|
group :test do
|
7
7
|
gem 'rake'
|
8
8
|
gem 'rspec'
|
9
|
-
gem 'tmrb'
|
10
9
|
gem 'simplecov'
|
11
10
|
gem 'aruba'
|
12
11
|
gem 'fuubar'
|
@@ -20,5 +19,10 @@ end
|
|
20
19
|
|
21
20
|
group :development do
|
22
21
|
gem 'tmrb'
|
22
|
+
gem 'debugger'
|
23
|
+
gem 'pry'
|
24
|
+
gem 'pry-doc'
|
25
|
+
gem 'awesome_print'
|
26
|
+
gem 'travis-lint'
|
23
27
|
gem 'activesupport'
|
24
28
|
end
|
data/Gemfile.lock
CHANGED
@@ -1,18 +1,15 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
command_exec (0.1.
|
5
|
-
|
6
|
-
|
4
|
+
command_exec (0.1.3)
|
5
|
+
activesupport
|
6
|
+
smart_colored
|
7
|
+
xml-simple
|
7
8
|
|
8
9
|
GEM
|
9
10
|
remote: http://rubygems.org/
|
10
11
|
specs:
|
11
|
-
|
12
|
-
Platform (>= 0.4.0)
|
13
|
-
open4
|
14
|
-
Platform (0.4.0)
|
15
|
-
activesupport (3.2.6)
|
12
|
+
activesupport (3.2.8)
|
16
13
|
i18n (~> 0.6)
|
17
14
|
multi_json (~> 1.0)
|
18
15
|
aruba (0.4.11)
|
@@ -20,28 +17,45 @@ GEM
|
|
20
17
|
cucumber (>= 1.1.1)
|
21
18
|
ffi (>= 1.0.11)
|
22
19
|
rspec (>= 2.7.0)
|
20
|
+
awesome_print (1.0.2)
|
23
21
|
builder (3.0.0)
|
24
|
-
childprocess (0.3.
|
22
|
+
childprocess (0.3.5)
|
25
23
|
ffi (~> 1.0, >= 1.0.6)
|
26
|
-
|
24
|
+
coderay (1.0.7)
|
25
|
+
columnize (0.3.6)
|
27
26
|
cucumber (1.2.1)
|
28
27
|
builder (>= 2.1.2)
|
29
28
|
diff-lcs (>= 1.1.3)
|
30
29
|
gherkin (~> 2.11.0)
|
31
30
|
json (>= 1.4.6)
|
31
|
+
debugger (1.2.0)
|
32
|
+
columnize (>= 0.3.1)
|
33
|
+
debugger-linecache (~> 1.1.1)
|
34
|
+
debugger-ruby_core_source (~> 1.1.3)
|
35
|
+
debugger-linecache (1.1.2)
|
36
|
+
debugger-ruby_core_source (>= 1.1.1)
|
37
|
+
debugger-ruby_core_source (1.1.3)
|
32
38
|
diff-lcs (1.1.3)
|
33
|
-
ffi (1.1.
|
39
|
+
ffi (1.1.5)
|
34
40
|
fuubar (1.0.0)
|
35
41
|
rspec (~> 2.0)
|
36
42
|
rspec-instafail (~> 0.2.0)
|
37
43
|
ruby-progressbar (~> 0.0.10)
|
38
|
-
gherkin (2.11.
|
44
|
+
gherkin (2.11.2)
|
39
45
|
json (>= 1.4.6)
|
40
46
|
github-markup (0.7.4)
|
41
|
-
|
42
|
-
|
47
|
+
hashr (0.0.22)
|
48
|
+
i18n (0.6.1)
|
49
|
+
json (1.7.5)
|
50
|
+
method_source (0.8)
|
43
51
|
multi_json (1.3.6)
|
44
|
-
|
52
|
+
pry (0.9.10)
|
53
|
+
coderay (~> 1.0.5)
|
54
|
+
method_source (~> 0.8)
|
55
|
+
slop (~> 3.3.1)
|
56
|
+
pry-doc (0.4.4)
|
57
|
+
pry (>= 0.9.9.6)
|
58
|
+
yard (~> 0.8.1)
|
45
59
|
rake (0.9.2.2)
|
46
60
|
redcarpet (2.1.1)
|
47
61
|
rspec (2.11.0)
|
@@ -49,18 +63,23 @@ GEM
|
|
49
63
|
rspec-expectations (~> 2.11.0)
|
50
64
|
rspec-mocks (~> 2.11.0)
|
51
65
|
rspec-core (2.11.1)
|
52
|
-
rspec-expectations (2.11.
|
66
|
+
rspec-expectations (2.11.3)
|
53
67
|
diff-lcs (~> 1.1.3)
|
54
68
|
rspec-instafail (0.2.4)
|
55
|
-
rspec-mocks (2.11.
|
69
|
+
rspec-mocks (2.11.2)
|
56
70
|
ruby-progressbar (0.0.10)
|
57
71
|
simplecov (0.6.4)
|
58
72
|
multi_json (~> 1.0)
|
59
73
|
simplecov-html (~> 0.5.3)
|
60
74
|
simplecov-html (0.5.3)
|
61
|
-
|
75
|
+
slop (3.3.3)
|
76
|
+
smart_colored (1.1.1)
|
77
|
+
thor (0.16.0)
|
62
78
|
tmrb (1.2.7)
|
63
79
|
thor
|
80
|
+
travis-lint (1.4.0)
|
81
|
+
hashr (>= 0.0.19)
|
82
|
+
xml-simple (1.1.1)
|
64
83
|
yard (0.8.2.1)
|
65
84
|
|
66
85
|
PLATFORMS
|
@@ -69,12 +88,17 @@ PLATFORMS
|
|
69
88
|
DEPENDENCIES
|
70
89
|
activesupport
|
71
90
|
aruba
|
91
|
+
awesome_print
|
72
92
|
command_exec!
|
93
|
+
debugger
|
73
94
|
fuubar
|
74
95
|
github-markup
|
96
|
+
pry
|
97
|
+
pry-doc
|
75
98
|
rake
|
76
99
|
redcarpet
|
77
100
|
rspec
|
78
101
|
simplecov
|
79
102
|
tmrb
|
103
|
+
travis-lint
|
80
104
|
yard
|
data/README.md
CHANGED
@@ -1,132 +1,752 @@
|
|
1
|
-
command-exec
|
2
|
-
===================================================
|
1
|
+
# command-exec -- execute shell commands with ease
|
3
2
|
|
4
|
-
|
3
|
+
[](https://codeclimate.com/github/maxmeyer/command_exec)
|
4
|
+
[](http://travis-ci.org/maxmeyer/command_exec)
|
5
5
|
|
6
|
-
|
6
|
+
## <a name="introduction">Introduction</a>
|
7
7
|
|
8
|
-
|
8
|
+
### Description
|
9
|
+
|
10
|
+
The name of the library is `command_exec`. It's helps you running programs and
|
11
|
+
check if the run was successful. It supports a vast amount of options you find
|
12
|
+
in the one of the following sections [usage](#usage).
|
13
|
+
|
14
|
+
`Example`:
|
9
15
|
|
10
16
|
```ruby
|
11
17
|
require 'command_exec'
|
12
18
|
|
13
|
-
#
|
14
|
-
command = CommandExec::Command.new( '
|
19
|
+
# command has to be in $PATH
|
20
|
+
command = CommandExec::Command.new( :echo , :parameter => 'hello world' )
|
15
21
|
command.run
|
22
|
+
p command.result
|
23
|
+
```
|
24
|
+
|
25
|
+
### Target "Group"
|
26
|
+
|
27
|
+
If you need a library to execute programs which do a job and then terminate,
|
28
|
+
`command_exec` is your friend.
|
29
|
+
|
30
|
+
If you need a library which supports error detection based on STDOUT, STDERR,
|
31
|
+
RETURN CODE and/or LOG FILE `command_exec` is the right choice.
|
32
|
+
|
33
|
+
### Limitations
|
34
|
+
|
35
|
+
The programs should NOT produce gigabytes of output (STDOUT, STDERR, LOG FILE)
|
36
|
+
to search for errors.
|
37
|
+
|
38
|
+
### Structure of documentation
|
39
|
+
|
40
|
+
<table>
|
41
|
+
<tr>
|
42
|
+
<th>Section</th>
|
43
|
+
<th>Description</th>
|
44
|
+
</tr>
|
45
|
+
<tr>
|
46
|
+
<td>Introduction</td>
|
47
|
+
<td>Metainformation</td>
|
48
|
+
</tr>
|
49
|
+
<tr>
|
50
|
+
<td>Usage</td>
|
51
|
+
<td>How to use the library</td>
|
52
|
+
</tr>
|
53
|
+
<tr>
|
54
|
+
<td>Options</td>
|
55
|
+
<td>Which options are available to parametrize the library</td>
|
56
|
+
</tr>
|
57
|
+
<tr>
|
58
|
+
<td>HowTo</td>
|
59
|
+
<td>How to do ... with library</td>
|
60
|
+
</tr>
|
61
|
+
<tr>
|
62
|
+
<td>Further reading</td>
|
63
|
+
<td>Other helpful information</td>
|
64
|
+
</tr>
|
65
|
+
</table>
|
66
|
+
|
67
|
+
## <a name="usage">Usage<a/>
|
68
|
+
|
69
|
+
### Gem versioning
|
70
|
+
|
71
|
+
This gem uses semantic versioning. The major version is increased when breaking
|
72
|
+
changes has been made. The minor version is increased if backward-compatiable
|
73
|
+
changes introduce new functionality. The patch version is increased if a bug
|
74
|
+
was fixed and the change is backward-compatible. Please see http://semver.org/
|
75
|
+
for more information.
|
76
|
+
|
77
|
+
### Ruby Version
|
78
|
+
|
79
|
+
This gem supports ruby up from 1.9.3.
|
80
|
+
|
81
|
+
### Install gem
|
82
|
+
|
83
|
+
Install the `command_exec`-gem via `rubygems` or whatever package manager (e.g. `bundler`) you like
|
84
|
+
to use.
|
85
|
+
|
86
|
+
```bash
|
87
|
+
gem install command_exec
|
88
|
+
```
|
89
|
+
|
90
|
+
### Include library
|
91
|
+
|
92
|
+
To include the library in your code, you could use this code snippet.
|
93
|
+
|
94
|
+
```ruby
|
95
|
+
require 'command_exec'
|
96
|
+
```
|
97
|
+
### Run command
|
98
|
+
|
99
|
+
There are two forms to execute a program. You could either use the long or the
|
100
|
+
short form. In both cases a `CommandExec::Command`-object will be returned.
|
101
|
+
|
102
|
+
```ruby
|
103
|
+
command = CommandExec::Command.new( :echo , :parameter => 'hello world' )
|
104
|
+
command.run
|
105
|
+
p command.result
|
106
|
+
```
|
107
|
+
|
108
|
+
```ruby
|
109
|
+
command = CommandExec::Command.execute( :echo , :parameter => 'hello world' )
|
110
|
+
p command.result
|
111
|
+
```
|
112
|
+
|
113
|
+
### <a name="result_of_command_execution">Result of command execution</a>
|
114
|
+
|
115
|
+
That `result`-object can be used to inspect the result of the command execution. It
|
116
|
+
supports several different methods, but only some are from interest for
|
117
|
+
external use. If you want a full list, please see the API-documentation at
|
118
|
+
[rdoc.info](http://www.rdoc.info/github/maxmeyer/command_exec/CommandExec/Process).
|
119
|
+
|
120
|
+
```ruby
|
121
|
+
result = command.result
|
122
|
+
|
123
|
+
# which executable was run
|
124
|
+
result.executable
|
125
|
+
|
126
|
+
# !!content!! of log file
|
127
|
+
result.log_file
|
128
|
+
|
129
|
+
# pid unter which the command was run
|
130
|
+
result.pid
|
16
131
|
|
17
|
-
#
|
18
|
-
|
132
|
+
#if failed, why
|
133
|
+
result.reason_for_failure
|
19
134
|
|
20
|
-
#
|
21
|
-
|
135
|
+
#return code of command
|
136
|
+
result.return_code
|
137
|
+
|
138
|
+
#status of command execution
|
139
|
+
result.status
|
140
|
+
|
141
|
+
#content of stderr
|
142
|
+
result.stderr
|
143
|
+
|
144
|
+
#content of stdout
|
145
|
+
result.stdout
|
146
|
+
```
|
147
|
+
|
148
|
+
### Serialize result of command execution
|
149
|
+
|
150
|
+
There are some methods which need a little more explanation. Those methods
|
151
|
+
return a string representation of the result.
|
152
|
+
|
153
|
+
```ruby
|
154
|
+
#return an array of lines
|
155
|
+
result.to_a
|
156
|
+
|
157
|
+
#return a hash
|
158
|
+
result.to_h
|
159
|
+
|
160
|
+
#serialize data to json
|
161
|
+
result.to_json
|
162
|
+
|
163
|
+
#serialize data to string
|
164
|
+
result.to_s
|
165
|
+
|
166
|
+
#serialize data to xml
|
167
|
+
result.to_xml
|
168
|
+
|
169
|
+
#serialize data to yaml
|
170
|
+
result.to_yaml
|
171
|
+
```
|
172
|
+
|
173
|
+
One can tell those methods which data should be returned. There are different
|
174
|
+
fields available:
|
175
|
+
|
176
|
+
<table>
|
177
|
+
<tr>
|
178
|
+
<th>Field</th>
|
179
|
+
<th>Symbol</th>
|
180
|
+
</tr>
|
181
|
+
<tr>
|
182
|
+
<td>Status</td>
|
183
|
+
<td>:status</td>
|
184
|
+
</tr>
|
185
|
+
<tr>
|
186
|
+
<td>Return code</td>
|
187
|
+
<td>:return_code</td>
|
188
|
+
</tr>
|
189
|
+
<tr>
|
190
|
+
<td>STDERR</td>
|
191
|
+
<td>:stderr</td>
|
192
|
+
</tr>
|
193
|
+
<tr>
|
194
|
+
<td>STDOUT</td>
|
195
|
+
<td>:stdout</td>
|
196
|
+
</tr>
|
197
|
+
<tr>
|
198
|
+
<td>Log file</td>
|
199
|
+
<td>:log_file</td>
|
200
|
+
</tr>
|
201
|
+
<tr>
|
202
|
+
<td>Process identitfier (PID)</td>
|
203
|
+
<td>:pid</td>
|
204
|
+
</tr>
|
205
|
+
<tr>
|
206
|
+
<td>Reason for failure</td>
|
207
|
+
<td>reason_for_failure</td>
|
208
|
+
</tr>
|
209
|
+
</table>
|
210
|
+
|
211
|
+
Now, some small examples:
|
212
|
+
|
213
|
+
```ruby
|
214
|
+
#result.<method>(field1,field2, ... , fieldn)
|
215
|
+
#result.<method>([field1,field2, ... , fieldn])
|
216
|
+
|
217
|
+
#all fields
|
218
|
+
result.to_a
|
219
|
+
|
220
|
+
#stderr and stdout only
|
221
|
+
result.to_a(:stderr, :stdout)
|
222
|
+
|
223
|
+
#stderr and stdout only (parameters given as a single array)
|
224
|
+
result.to_a([:stderr, :stdout])
|
225
|
+
```
|
226
|
+
|
227
|
+
## Extended usage
|
228
|
+
|
229
|
+
There are multiple ways to tell `command_exec` about a command:
|
230
|
+
|
231
|
+
### Search command in PATH
|
232
|
+
|
233
|
+
If the first parameter of `run` and `execute` is a `Symbol` the library will
|
234
|
+
search for the command in the paths given in the $PATH-shell-variable.
|
235
|
+
|
236
|
+
```ruby
|
237
|
+
command = CommandExec::Command.execute( :echo ,
|
238
|
+
:parameter => 'hello world',
|
239
|
+
)
|
240
|
+
p command.result
|
241
|
+
```
|
242
|
+
|
243
|
+
### Path to command
|
244
|
+
|
245
|
+
If you prefer to use a full qualified path, this is possible as well.
|
246
|
+
|
247
|
+
```ruby
|
248
|
+
command = CommandExec::Command.execute( '/bin/echo' ,
|
249
|
+
:parameter => 'hello world',
|
250
|
+
)
|
251
|
+
p command.result
|
252
|
+
```
|
253
|
+
|
254
|
+
It also supports relative paths. But be aware to tell the library the correct
|
255
|
+
one. The base path for relative ones is the working directory of the *library*,
|
256
|
+
not the working directory of the command (see section "[Working
|
257
|
+
directory](#working_directory)" about that).
|
258
|
+
|
259
|
+
|
260
|
+
```ruby
|
261
|
+
Dir.chdir('/tmp') do
|
262
|
+
command = CommandExec::Command.execute( '../bin/echo' ,
|
263
|
+
:parameter => 'hello world',
|
264
|
+
:logger => Logger.new($stderr)
|
265
|
+
)
|
266
|
+
p command.result
|
267
|
+
end
|
22
268
|
```
|
23
269
|
|
24
270
|
## Options
|
25
271
|
|
26
|
-
|
272
|
+
### Logging
|
273
|
+
|
274
|
+
`command_exec` makes use of the Ruby `Logger`-class. If you would like to use
|
275
|
+
another class/gem, nevermind, but it has to be compatible with the `Logger`-API.
|
276
|
+
|
277
|
+
To make it easier for you, `command_exec` provides a `:logger` option. It
|
278
|
+
defaults to `Logger.new($stderr)`.
|
27
279
|
|
28
280
|
```ruby
|
29
|
-
command = CommandExec::Command.
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
command.
|
281
|
+
command = CommandExec::Command.execute( :echo ,
|
282
|
+
:parameter => 'hello world',
|
283
|
+
:logger => Logger.new($stderr),
|
284
|
+
)
|
285
|
+
p command.result
|
286
|
+
```
|
287
|
+
|
288
|
+
If you prefer more or less information you can make use of the
|
289
|
+
`:lib_log_level`-option. With one exception, those log levels are the same like in
|
290
|
+
the `Logger`-class. Additionally you can use `:silent` to suppress all output
|
291
|
+
of the library, if you use the `open3` and not the `system` runner. If you
|
292
|
+
choose to use the system runner, STDOUT from the command won't be captured.
|
293
|
+
|
294
|
+
|
295
|
+
<table>
|
296
|
+
<tr>
|
297
|
+
<td><strong>Option value</strong></td>
|
298
|
+
<td><strong>Logger loglevel</strong></td>
|
299
|
+
</tr>
|
300
|
+
<tr>
|
301
|
+
<td>:debug</td>
|
302
|
+
<td>Logger::DEBUG</td>
|
303
|
+
</tr>
|
304
|
+
<tr>
|
305
|
+
<td>:info</td>
|
306
|
+
<td>Logger::INFO</td>
|
307
|
+
</tr>
|
308
|
+
<tr>
|
309
|
+
<td>:warn</td>
|
310
|
+
<td>Logger::WARN</td>
|
311
|
+
</tr>
|
312
|
+
<tr>
|
313
|
+
<td>:error</td>
|
314
|
+
<td>Logger::ERROR</td>
|
315
|
+
</tr>
|
316
|
+
<tr>
|
317
|
+
<td>:fatal</td>
|
318
|
+
<td>Logger::FATAL</td>
|
319
|
+
</tr>
|
320
|
+
<tr>
|
321
|
+
<td>:unknown</td>
|
322
|
+
<td>Logger::UNKNOWN</td>
|
323
|
+
</tr>
|
324
|
+
<tr>
|
325
|
+
<td>:silent</td>
|
326
|
+
<td>no output (log device is set to nil)</td>
|
327
|
+
</tr>
|
328
|
+
</table>
|
329
|
+
|
330
|
+
|
331
|
+
```ruby
|
332
|
+
command = CommandExec::Command.execute( :echo ,
|
333
|
+
:parameter => 'hello world' ,
|
334
|
+
:lib_log_level => :debug,
|
335
|
+
)
|
336
|
+
p command.result
|
34
337
|
```
|
35
338
|
|
36
|
-
|
339
|
+
### Command options and parameter
|
340
|
+
|
341
|
+
The next two options (command options and command parameters) are very similar.
|
342
|
+
Both will be used to build the command which should be executed. The main
|
343
|
+
difference is the position of given string in the command string.
|
344
|
+
|
345
|
+
|
346
|
+
```
|
347
|
+
<command> <options> <parameter>
|
348
|
+
```
|
349
|
+
|
350
|
+
So, if you don't want to use the `options`- and/or the `parameter`-option, you
|
351
|
+
don't need to do it. But may be there are situations, where you would like to
|
352
|
+
be as concise as possible.
|
353
|
+
|
354
|
+
|
355
|
+
Recommended:
|
37
356
|
|
38
357
|
```ruby
|
39
|
-
command = CommandExec::Command.
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
command.
|
358
|
+
command = CommandExec::Command.execute( :ls ,
|
359
|
+
:options => '-al',
|
360
|
+
:parameter => '/bin',
|
361
|
+
)
|
362
|
+
p command.result
|
44
363
|
```
|
45
364
|
|
46
|
-
|
365
|
+
But also valid:
|
47
366
|
|
48
|
-
|
49
|
-
|
367
|
+
```ruby
|
368
|
+
command = CommandExec::Command.execute( :ls ,
|
369
|
+
:options => '-al /bin',
|
370
|
+
)
|
371
|
+
p command.result
|
372
|
+
```
|
373
|
+
|
374
|
+
Or:
|
50
375
|
|
51
376
|
```ruby
|
52
|
-
command = CommandExec::Command.
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
command.run
|
377
|
+
command = CommandExec::Command.execute( :ls ,
|
378
|
+
:parameter => '-al /bin',
|
379
|
+
)
|
380
|
+
p command.result
|
57
381
|
```
|
58
382
|
|
59
|
-
|
383
|
+
Please check if you use single or double quotes correctly! `command_exec` takes
|
384
|
+
the parameters and options as given. That's why
|
60
385
|
|
61
|
-
|
386
|
+
```ruby
|
387
|
+
#will succeed
|
388
|
+
#see debug output for reason
|
389
|
+
command = CommandExec::Command.execute( :echo ,
|
390
|
+
:options => '-e',
|
391
|
+
:parameter => "\"Thats a string\n with a newline\"",
|
392
|
+
:lib_log_level => :debug,
|
393
|
+
)
|
394
|
+
p command.result
|
395
|
+
```
|
396
|
+
|
397
|
+
isn't the same like
|
62
398
|
|
63
399
|
```ruby
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
400
|
+
#will fail
|
401
|
+
#see debug output for reason
|
402
|
+
command = CommandExec::Command.execute( :echo ,
|
403
|
+
:options => '-e',
|
404
|
+
:parameter => "Thats a string\n with a newline",
|
405
|
+
:lib_log_level => :debug,
|
406
|
+
)
|
407
|
+
p command.result
|
69
408
|
```
|
70
409
|
|
71
|
-
|
410
|
+
### <a name="log_file">Command log file</a>
|
72
411
|
|
73
|
-
|
74
|
-
|
412
|
+
If the command creates a log file, you can tell `command_exec` about that file
|
413
|
+
via the `:log_file`-option. Honestly, this option only makes sense if you
|
414
|
+
configure `command_exec`to search for errors in the file (please see the
|
415
|
+
chapter about [Error detection](#error_detection) for further information about
|
416
|
+
that).
|
75
417
|
|
76
418
|
```ruby
|
77
|
-
command = CommandExec::Command.
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
command.
|
419
|
+
command = CommandExec::Command.execute( :ls ,
|
420
|
+
:options => '-al',
|
421
|
+
:log_file => '/path/to/log_file',
|
422
|
+
)
|
423
|
+
p command.result
|
82
424
|
```
|
83
425
|
|
84
|
-
|
426
|
+
### Command search path
|
85
427
|
|
86
|
-
|
87
|
-
|
88
|
-
output.
|
428
|
+
If you need to change the paths where a command can be found, you could use the
|
429
|
+
`:search_path`-option. It defaults to those paths found in $PATH.
|
89
430
|
|
431
|
+
It supports multiple values as `Array`:
|
90
432
|
|
91
433
|
```ruby
|
92
|
-
command = CommandExec::Command.
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
command.run
|
434
|
+
command = CommandExec::Command.execute( :ls ,
|
435
|
+
:options => '-al',
|
436
|
+
:search_paths => [ '/bin' ],
|
437
|
+
)
|
438
|
+
p command.result
|
98
439
|
```
|
99
440
|
|
100
|
-
|
441
|
+
Or single values as `String`:
|
442
|
+
|
443
|
+
```ruby
|
444
|
+
command = CommandExec::Command.execute( :ls ,
|
445
|
+
:options => '-al',
|
446
|
+
:search_paths => '/bin',
|
447
|
+
)
|
448
|
+
p command.result
|
449
|
+
```
|
101
450
|
|
102
|
-
|
103
|
-
|
451
|
+
### <a name="error_detection">Error detection</a>
|
452
|
+
|
453
|
+
`command_exec` is capable of searching for errors. To enable error detection
|
454
|
+
you need to activate it via the `:error_detection_on`-option. It supports error
|
455
|
+
detection on:
|
456
|
+
|
457
|
+
<table>
|
458
|
+
<tr>
|
459
|
+
<td><strong>Search in...</strong></td>
|
460
|
+
<td><strong>Symbol</strong></td>
|
461
|
+
</tr>
|
462
|
+
<tr>
|
463
|
+
<td>Return code</td>
|
464
|
+
<td>:return_code</td>
|
465
|
+
</tr>
|
466
|
+
<tr>
|
467
|
+
<td>STDOUT</td>
|
468
|
+
<td>:stdout</td>
|
469
|
+
</tr>
|
470
|
+
<tr>
|
471
|
+
<td>STDERR</td>
|
472
|
+
<td>:stderr</td>
|
473
|
+
</tr>
|
474
|
+
<tr>
|
475
|
+
<td>Log file</td>
|
476
|
+
<td>:log_file</td>
|
477
|
+
</tr>
|
478
|
+
</table>
|
479
|
+
|
480
|
+
But you need to provide information, what item indicates an error.
|
481
|
+
|
482
|
+
<table>
|
483
|
+
<tr>
|
484
|
+
<td><strong>Indicator for...</strong></td>
|
485
|
+
<td><strong>Options</strong></td>
|
486
|
+
<td><strong>Type</strong></td>
|
487
|
+
</tr>
|
488
|
+
<tr>
|
489
|
+
<td>Return code</td>
|
490
|
+
<td>
|
491
|
+
:allowed_return_code<br/>
|
492
|
+
:forbidden_return_code
|
493
|
+
</td>
|
494
|
+
<td>
|
495
|
+
Array
|
496
|
+
</td>
|
497
|
+
</tr>
|
498
|
+
<tr>
|
499
|
+
<td>STDERR</td>
|
500
|
+
<td>
|
501
|
+
:allowed_words_in_stderr<br/>
|
502
|
+
:forbidden_words_in_stderr
|
503
|
+
</td>
|
504
|
+
<td>
|
505
|
+
Array
|
506
|
+
</td>
|
507
|
+
</tr>
|
508
|
+
<tr>
|
509
|
+
<td>STDOUT</td>
|
510
|
+
<td>
|
511
|
+
:allowed_words_in_stdout<br/>
|
512
|
+
:forbidden_words_in_stdout
|
513
|
+
</td>
|
514
|
+
<td>
|
515
|
+
Array
|
516
|
+
</td>
|
517
|
+
</tr>
|
518
|
+
<tr>
|
519
|
+
<td>Log file</td>
|
520
|
+
<td>
|
521
|
+
:allowed_words_in_log_file<br/>
|
522
|
+
:forbidden_words_in_log_file
|
523
|
+
</td>
|
524
|
+
<td>
|
525
|
+
Array
|
526
|
+
</td>
|
527
|
+
</tr>
|
528
|
+
</table>
|
529
|
+
|
530
|
+
*Return code*
|
531
|
+
|
532
|
+
If the command returns helpful return codes, those can be used to check if an
|
533
|
+
error occured. You can tell `command_exec` about allowed or forbidden return
|
534
|
+
codes.
|
104
535
|
|
105
|
-
### Successfull
|
106
536
|
|
537
|
+
```ruby
|
538
|
+
#All error codes except `0` will be detected as an error.
|
539
|
+
command = CommandExec::Command.execute( :false ,
|
540
|
+
:error_detection_on => [:return_code],
|
541
|
+
:error_indicators => {
|
542
|
+
:allowed_return_code => [0],
|
543
|
+
},
|
544
|
+
)
|
545
|
+
p command.result
|
546
|
+
|
547
|
+
#If the command exits with a return code of `1`, this will be detected as an
|
548
|
+
#error.
|
549
|
+
command = CommandExec::Command.execute( :false ,
|
550
|
+
:error_detection_on => [:return_code],
|
551
|
+
:error_indicators => {
|
552
|
+
:forbidden_return_code => [1],
|
553
|
+
},
|
554
|
+
)
|
555
|
+
p command.result
|
107
556
|
```
|
108
|
-
|
557
|
+
|
558
|
+
In the case of the detection of errors `command_exec`defaults to:
|
559
|
+
|
560
|
+
```ruby
|
561
|
+
:error_detection_on => [:return_code],
|
562
|
+
:allowed_return_code => [0],
|
109
563
|
```
|
110
564
|
|
111
|
-
|
565
|
+
*STDOUT*
|
112
566
|
|
567
|
+
`command_exec` can search for errors in STDOUT. To enable this functionality,
|
568
|
+
you need to set the `:error_detection_on`-option on ':stdout'. Furthermore you
|
569
|
+
need to tell the library, what strings are error indicators
|
570
|
+
(`forbidden_words_in_stdout`). If there are some strings which contain the
|
571
|
+
error string(s), but are no errors, you need to use the
|
572
|
+
`allowed_words_in_stdout`-option. The same is true, if the allowed word is in
|
573
|
+
the same line.
|
574
|
+
|
575
|
+
```ruby
|
576
|
+
#Simple error search
|
577
|
+
#will fail
|
578
|
+
command = CommandExec::Command.execute( :echo ,
|
579
|
+
:options => '-e',
|
580
|
+
:parameter => "\"wow, a test. That's great.\nBut an error occured in this line\"",
|
581
|
+
:error_detection_on => [:stdout],
|
582
|
+
:error_indicators => {
|
583
|
+
:forbidden_words_in_stdout => %w{ error }
|
584
|
+
},
|
585
|
+
)
|
586
|
+
p command.result
|
587
|
+
|
588
|
+
#error indicator in string, which is no error
|
589
|
+
#will succeed
|
590
|
+
command = CommandExec::Command.execute( :echo ,
|
591
|
+
:options => '-e',
|
592
|
+
:parameter => "\"wow, a test. That's great.\nBut no error occured in this line\"",
|
593
|
+
:error_detection_on => [:stdout],
|
594
|
+
:error_indicators => {
|
595
|
+
:forbidden_words_in_stdout => %w{ error },
|
596
|
+
:allowed_words_in_stdout => ["no error occured"] ,
|
597
|
+
},
|
598
|
+
)
|
599
|
+
p command.result
|
600
|
+
|
601
|
+
#error indicator in same line, which is no error
|
602
|
+
#will succeed
|
603
|
+
command = CommandExec::Command.execute( :echo ,
|
604
|
+
:options => '-e',
|
605
|
+
:parameter => "\"wow, a test. That's great.\nBut no error occured in this line because of some other string\"",
|
606
|
+
:error_detection_on => [:stdout],
|
607
|
+
:error_indicators => {
|
608
|
+
:forbidden_words_in_stdout => %w{ error },
|
609
|
+
:allowed_words_in_stdout => ["some other string"] ,
|
610
|
+
},
|
611
|
+
)
|
612
|
+
p command.result
|
113
613
|
```
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
[
|
119
|
-
|
120
|
-
[
|
614
|
+
|
615
|
+
*STDERR*
|
616
|
+
|
617
|
+
The same is true for STDERR. You need to activate the error detection via
|
618
|
+
`:error_detection_on => [:stderr]`. The error indicators can be given via
|
619
|
+
`:forbidden_words_in_stderr => %w{ error }` and `:allowed_words_in_stdout =>
|
620
|
+
["some other string"]`.
|
621
|
+
|
622
|
+
```ruby
|
623
|
+
#will fail
|
624
|
+
command = CommandExec::Command.execute( :echo ,
|
625
|
+
:options => '-e',
|
626
|
+
:parameter => "\"wow, a test. That's great.\nBut an error occured in this line\" >&2",
|
627
|
+
:error_detection_on => [:stderr],
|
628
|
+
:error_indicators => {
|
629
|
+
:forbidden_words_in_stderr => %w{ error },
|
630
|
+
},
|
631
|
+
)
|
632
|
+
p command.result
|
121
633
|
```
|
122
634
|
|
123
|
-
|
635
|
+
*LOG FILE*
|
636
|
+
|
637
|
+
To search for errors in the log file a command created during execution, you
|
638
|
+
need to provide the information where `command_exec` finds the log file (see
|
639
|
+
section [Command Log file](#log_file)).
|
124
640
|
|
641
|
+
The options are very similar to those for STDERR and STDOUT: To activate error
|
642
|
+
detection for log files use `:error_detection_on => [:log_file]`. The error
|
643
|
+
indicators can be given via `:forbidden_words_in_log_file => %w{ error }` and
|
644
|
+
`:allowed_words_in_log_file => ["some other string"]`.
|
645
|
+
|
646
|
+
```ruby
|
647
|
+
File.open('/tmp/test.log', 'w') do |f|
|
648
|
+
f.write "wow, a test. That's great.\nBut an error occured in this line"
|
649
|
+
end
|
650
|
+
|
651
|
+
#will fail
|
652
|
+
command = CommandExec::Command.execute( :echo ,
|
653
|
+
:error_detection_on => [:log_file],
|
654
|
+
:log_file => '/tmp/test.log',
|
655
|
+
:error_indicators => {
|
656
|
+
:forbidden_words_in_log_file => %w{ error },
|
657
|
+
},
|
658
|
+
)
|
659
|
+
p command.result
|
125
660
|
```
|
126
|
-
|
127
|
-
|
661
|
+
|
662
|
+
### <a name="working_directory">Working directory</a>
|
663
|
+
|
664
|
+
To change the working directory for the command you can use the `:working_directory`-option.
|
665
|
+
|
666
|
+
```ruby
|
667
|
+
command = CommandExec::Command.execute( :ls ,
|
668
|
+
:options => '-al',
|
669
|
+
:working_directory => '/tmp',
|
670
|
+
)
|
671
|
+
p command.result
|
128
672
|
```
|
129
673
|
|
674
|
+
### Error reaction
|
675
|
+
|
676
|
+
If an error occured, `command_exec` can raise an exception, 'throw' an error or
|
677
|
+
do nothing at all. Besides the configured option, on every run it returns the
|
678
|
+
result for the run (see [Result of command
|
679
|
+
execution](#result_of_command_execution) for more details).
|
680
|
+
|
681
|
+
*Raise an exception aka error*
|
682
|
+
|
683
|
+
If an error occured during command execution, you can tell `command_exec` to
|
684
|
+
raise an exception.
|
685
|
+
|
686
|
+
```ruby
|
687
|
+
begin
|
688
|
+
command = CommandExec::Command.execute( :false ,
|
689
|
+
:on_error_do => :raise_error,
|
690
|
+
)
|
691
|
+
rescue CommandExec::Exceptions::CommandExecutionFailed => e
|
692
|
+
puts e.message
|
693
|
+
end
|
694
|
+
```
|
695
|
+
|
696
|
+
*Throw error*
|
697
|
+
|
698
|
+
If you prefer not to use execptions, you can use ruby's
|
699
|
+
`throw`-`catch`-mechanism.
|
700
|
+
|
701
|
+
```ruby
|
702
|
+
catch :command_execution_failed do
|
703
|
+
command = CommandExec::Command.execute( :false ,
|
704
|
+
:on_error_do => :throw_error,
|
705
|
+
)
|
706
|
+
end
|
707
|
+
```
|
708
|
+
|
709
|
+
### Runner
|
710
|
+
|
711
|
+
Today there are two runners available: `:open3` and `system`. Use the first one
|
712
|
+
if you want `:stdout` and `:stderr` to be captured and searched for errors. If
|
713
|
+
you're only interested in the `:return_code` you could use the
|
714
|
+
`:system`-runner. Please be aware, that using the `system`-runner + error
|
715
|
+
detection on `stdout`, `stderr` is not working as you might expect.
|
716
|
+
|
717
|
+
```ruby
|
718
|
+
#will fail
|
719
|
+
command = CommandExec::Command.execute( :echo ,
|
720
|
+
:options => '-e',
|
721
|
+
:parameter => "\"wow, a test. That's great.\nBut an error occured in this line\"",
|
722
|
+
:error_detection_on => [:stdout],
|
723
|
+
:error_indicators => {
|
724
|
+
:forbidden_words_in_stdout => %w{ error }
|
725
|
+
},
|
726
|
+
:run_via => :open3,
|
727
|
+
)
|
728
|
+
p command.result
|
729
|
+
|
730
|
+
#will succeed, because stdout was not caputured
|
731
|
+
command = CommandExec::Command.execute( :echo ,
|
732
|
+
:options => '-e',
|
733
|
+
:parameter => "\"wow, a test. That's great.\nBut an error occured in this line\"",
|
734
|
+
:error_detection_on => [:stdout],
|
735
|
+
:error_indicators => {
|
736
|
+
:forbidden_words_in_stdout => %w{ error }
|
737
|
+
},
|
738
|
+
:run_via => :system,
|
739
|
+
)
|
740
|
+
p command.result
|
741
|
+
```
|
742
|
+
## HowTo
|
743
|
+
|
744
|
+
TBD
|
745
|
+
|
746
|
+
## Further Reading
|
747
|
+
|
748
|
+
* API-documentation: http://rdoc.info/github/maxmeyer/command_exec/frames
|
749
|
+
|
130
750
|
## Dependencies
|
131
751
|
|
132
752
|
Please see the gemspec for runtime dependencies and the 'Gemfile' for
|
@@ -136,6 +756,21 @@ development dependencies.
|
|
136
756
|
|
137
757
|
Please see TODO.md for enhancements which are planned for implementation.
|
138
758
|
|
759
|
+
## Development
|
760
|
+
|
761
|
+
1. Fork it
|
762
|
+
2. Create your remote (`git remote add <your_remote_repo> <path_to_repo>`)
|
763
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
764
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
765
|
+
4. Push to the branch (`git push <your_remote_repo> my-new-feature`)
|
766
|
+
5. Create new Pull Request
|
767
|
+
|
768
|
+
The API-documentation can be found at
|
769
|
+
http://rdoc.info/github/maxmeyer/command_exec/frames
|
770
|
+
|
771
|
+
Please see 'http://git-scm.com/book' first if you have further questions about
|
772
|
+
`git`.
|
773
|
+
|
139
774
|
## Copyright
|
140
775
|
|
141
776
|
(c) 2012-, Max Meyer
|