linebook 0.7.0 → 0.8.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/History +8 -0
- data/HowTo/Setup/Debian +75 -0
- data/HowTo/Setup/SLES +87 -0
- data/HowTo/Setup/Ubuntu +71 -0
- data/HowTo/Setup/openSUSE +75 -0
- data/HowTo/Switch Users +73 -0
- data/lib/linebook/os/linux.rb +24 -199
- data/lib/linebook/os/linux/utilities.rb +226 -0
- data/lib/linebook/os/posix.rb +268 -78
- data/lib/linebook/os/posix/utilities.rb +726 -0
- data/lib/linebook/os/posix/variable.rb +91 -0
- data/lib/linebook/os/ubuntu.rb +1 -1
- data/lib/linebook/shell.rb +3 -3
- data/lib/linebook/version.rb +1 -1
- metadata +24 -12
- data/lib/linebook/os/unix.rb +0 -462
@@ -0,0 +1,226 @@
|
|
1
|
+
# Generated by Linecook
|
2
|
+
|
3
|
+
module Linebook
|
4
|
+
module Os
|
5
|
+
module Linux
|
6
|
+
module Utilities
|
7
|
+
# Returns true if the group exists as determined by checking /etc/group.
|
8
|
+
def group?(name)
|
9
|
+
# grep "^<%= name %>:" /etc/group >/dev/null 2>&1
|
10
|
+
write "grep \"^"; write(( name ).to_s); write ":\" /etc/group >/dev/null 2>&1"
|
11
|
+
chain_proxy
|
12
|
+
end
|
13
|
+
|
14
|
+
def _group?(*args, &block) # :nodoc:
|
15
|
+
str = capture_str { group?(*args, &block) }
|
16
|
+
str.strip!
|
17
|
+
str
|
18
|
+
end
|
19
|
+
|
20
|
+
# Create a new group.
|
21
|
+
# {[Spec]}[http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/groupadd.html]
|
22
|
+
def groupadd(group, options={})
|
23
|
+
execute 'groupadd', group, options
|
24
|
+
chain_proxy
|
25
|
+
end
|
26
|
+
|
27
|
+
def _groupadd(*args, &block) # :nodoc:
|
28
|
+
str = capture_str { groupadd(*args, &block) }
|
29
|
+
str.strip!
|
30
|
+
str
|
31
|
+
end
|
32
|
+
|
33
|
+
# Delete a group.
|
34
|
+
# {[Spec]}[http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/groupdel.html]
|
35
|
+
def groupdel(group)
|
36
|
+
execute 'groupdel', group
|
37
|
+
chain_proxy
|
38
|
+
end
|
39
|
+
|
40
|
+
def _groupdel(*args, &block) # :nodoc:
|
41
|
+
str = capture_str { groupdel(*args, &block) }
|
42
|
+
str.strip!
|
43
|
+
str
|
44
|
+
end
|
45
|
+
|
46
|
+
# Modify a group.
|
47
|
+
# {[Spec]}[http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/groupmod.html]
|
48
|
+
def groupmod(group, options={})
|
49
|
+
execute 'groupmod', group, options
|
50
|
+
chain_proxy
|
51
|
+
end
|
52
|
+
|
53
|
+
def _groupmod(*args, &block) # :nodoc:
|
54
|
+
str = capture_str { groupmod(*args, &block) }
|
55
|
+
str.strip!
|
56
|
+
str
|
57
|
+
end
|
58
|
+
|
59
|
+
# Display a group.
|
60
|
+
# {[Spec]}[http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/groups.html]
|
61
|
+
def groups(user)
|
62
|
+
execute 'groups', user
|
63
|
+
chain_proxy
|
64
|
+
end
|
65
|
+
|
66
|
+
def _groups(*args, &block) # :nodoc:
|
67
|
+
str = capture_str { groups(*args, &block) }
|
68
|
+
str.strip!
|
69
|
+
str
|
70
|
+
end
|
71
|
+
|
72
|
+
# Compress or expand files.
|
73
|
+
# {[Spec]}[http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/gzip.html]
|
74
|
+
def gzip(*files)
|
75
|
+
execute 'gzip', *files
|
76
|
+
chain_proxy
|
77
|
+
end
|
78
|
+
|
79
|
+
def _gzip(*args, &block) # :nodoc:
|
80
|
+
str = capture_str { gzip(*args, &block) }
|
81
|
+
str.strip!
|
82
|
+
str
|
83
|
+
end
|
84
|
+
|
85
|
+
# Show or set the system's host name.
|
86
|
+
# {[Spec]}[http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/hostname.html]
|
87
|
+
def hostname(name=nil)
|
88
|
+
execute 'hostname', name
|
89
|
+
chain_proxy
|
90
|
+
end
|
91
|
+
|
92
|
+
def _hostname(*args, &block) # :nodoc:
|
93
|
+
str = capture_str { hostname(*args, &block) }
|
94
|
+
str.strip!
|
95
|
+
str
|
96
|
+
end
|
97
|
+
|
98
|
+
# Copy files and set attributes.
|
99
|
+
# {[Spec]}[http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/install.html]
|
100
|
+
def install(source, dest, options={})
|
101
|
+
execute 'install', source, dest, options
|
102
|
+
chain_proxy
|
103
|
+
end
|
104
|
+
|
105
|
+
def _install(*args, &block) # :nodoc:
|
106
|
+
str = capture_str { install(*args, &block) }
|
107
|
+
str.strip!
|
108
|
+
str
|
109
|
+
end
|
110
|
+
|
111
|
+
# Generate or check MD5 message digests.
|
112
|
+
# {[Spec]}[http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/md5sum.html]
|
113
|
+
def md5sum(*files)
|
114
|
+
execute 'md5sum', *files
|
115
|
+
chain_proxy
|
116
|
+
end
|
117
|
+
|
118
|
+
def _md5sum(*args, &block) # :nodoc:
|
119
|
+
str = capture_str { md5sum(*args, &block) }
|
120
|
+
str.strip!
|
121
|
+
str
|
122
|
+
end
|
123
|
+
|
124
|
+
# Make temporary file name (unique)
|
125
|
+
# {[Spec]}[http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/mktemp.html]
|
126
|
+
def mktemp(template, options={})
|
127
|
+
execute 'mktemp', template, options
|
128
|
+
chain_proxy
|
129
|
+
end
|
130
|
+
|
131
|
+
def _mktemp(*args, &block) # :nodoc:
|
132
|
+
str = capture_str { mktemp(*args, &block) }
|
133
|
+
str.strip!
|
134
|
+
str
|
135
|
+
end
|
136
|
+
|
137
|
+
# Switches to the specified user for the duration of a block. The current ENV
|
138
|
+
# and pwd are preserved.
|
139
|
+
# {[Spec]}[http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/su.html]
|
140
|
+
def su(user='root', options={})
|
141
|
+
path = capture_script(options) do
|
142
|
+
functions.each_value do |function|
|
143
|
+
writeln function
|
144
|
+
end
|
145
|
+
yield
|
146
|
+
end
|
147
|
+
execute 'su', user, path, :m => true
|
148
|
+
chain_proxy
|
149
|
+
end
|
150
|
+
|
151
|
+
def _su(*args, &block) # :nodoc:
|
152
|
+
str = capture_str { su(*args, &block) }
|
153
|
+
str.strip!
|
154
|
+
str
|
155
|
+
end
|
156
|
+
|
157
|
+
# File archiver. {[Spec]}[http://pubs.opengroup.org/onlinepubs/007908799/xcu/tar.html]
|
158
|
+
def tar(key, *files)
|
159
|
+
execute 'tar', key, files
|
160
|
+
chain_proxy
|
161
|
+
end
|
162
|
+
|
163
|
+
def _tar(*args, &block) # :nodoc:
|
164
|
+
str = capture_str { tar(*args, &block) }
|
165
|
+
str.strip!
|
166
|
+
str
|
167
|
+
end
|
168
|
+
|
169
|
+
# Returns true if the user exists as determined by id.
|
170
|
+
def user?(name)
|
171
|
+
# id <%= quote(name) %> >/dev/null 2>&1
|
172
|
+
write "id "; write(( quote(name) ).to_s); write " >/dev/null 2>&1"
|
173
|
+
chain_proxy
|
174
|
+
end
|
175
|
+
|
176
|
+
def _user?(*args, &block) # :nodoc:
|
177
|
+
str = capture_str { user?(*args, &block) }
|
178
|
+
str.strip!
|
179
|
+
str
|
180
|
+
end
|
181
|
+
|
182
|
+
# Create a new user or update default new user information.
|
183
|
+
# {[Spec]}[http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/useradd.html]
|
184
|
+
def useradd(login, options={})
|
185
|
+
execute 'useradd', login, options
|
186
|
+
chain_proxy
|
187
|
+
end
|
188
|
+
|
189
|
+
def _useradd(*args, &block) # :nodoc:
|
190
|
+
str = capture_str { useradd(*args, &block) }
|
191
|
+
str.strip!
|
192
|
+
str
|
193
|
+
end
|
194
|
+
|
195
|
+
# Delete a user account and related files.
|
196
|
+
# {[Spec]}[http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/userdel.html]
|
197
|
+
def userdel(login, options={})
|
198
|
+
# TODO - look into other things that might need to happen before:
|
199
|
+
# * kill processes belonging to user
|
200
|
+
# * remove at/cron/print jobs etc.
|
201
|
+
execute 'userdel', login, options
|
202
|
+
chain_proxy
|
203
|
+
end
|
204
|
+
|
205
|
+
def _userdel(*args, &block) # :nodoc:
|
206
|
+
str = capture_str { userdel(*args, &block) }
|
207
|
+
str.strip!
|
208
|
+
str
|
209
|
+
end
|
210
|
+
|
211
|
+
# Modify a user account.
|
212
|
+
# {[Spec]}[http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/usermod.html]
|
213
|
+
def usermod(login, options={})
|
214
|
+
execute 'usermod', login, options
|
215
|
+
chain_proxy
|
216
|
+
end
|
217
|
+
|
218
|
+
def _usermod(*args, &block) # :nodoc:
|
219
|
+
str = capture_str { usermod(*args, &block) }
|
220
|
+
str.strip!
|
221
|
+
str
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
data/lib/linebook/os/posix.rb
CHANGED
@@ -2,26 +2,33 @@
|
|
2
2
|
|
3
3
|
module Linebook
|
4
4
|
module Os
|
5
|
+
# Defines POSIX-compliant functionality, based on the {IEEE 1003.1-2008
|
6
|
+
# standard }[http://pubs.opengroup.org/onlinepubs/9699919799]. See the online
|
7
|
+
# documentation for:
|
8
|
+
#
|
9
|
+
# * {POSIX Shell Command Language
|
10
|
+
# }[http://pubs.opengroup.org/onlinepubs/9699919799/utilities/xcu_chap02.html]
|
11
|
+
# * {Special Built-in Utilities
|
12
|
+
# }[http://pubs.opengroup.org/onlinepubs/9699919799/idx/sbi.html]
|
13
|
+
# * {Standard Utilties
|
14
|
+
# }[http://pubs.opengroup.org/onlinepubs/9699919799/idx/utilities.html]
|
15
|
+
#
|
16
|
+
# In addition, the {Shell Hater's Handbook}[http://shellhaters.heroku.com/]
|
17
|
+
# provides a nice index of the relevant information.
|
18
|
+
#
|
5
19
|
module Posix
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
obj.nil? || obj.to_s.strip.empty?
|
10
|
-
end
|
20
|
+
require 'linebook/os/posix/variable'
|
21
|
+
require 'linebook/os/posix/utilities'
|
22
|
+
include Utilities
|
11
23
|
|
12
|
-
#
|
13
|
-
|
14
|
-
|
15
|
-
arg = arg.to_s
|
16
|
-
quoted?(arg) || !quote?(arg) ? arg : "\"#{arg}\""
|
24
|
+
# Returns "$0", the program name.
|
25
|
+
def program_name
|
26
|
+
Variable.new(0)
|
17
27
|
end
|
18
28
|
|
19
|
-
#
|
20
|
-
|
21
|
-
|
22
|
-
def quote?(str)
|
23
|
-
c = str[0]
|
24
|
-
c == ?- || c == ?+ || quoted?(str) ? false : true
|
29
|
+
# Encloses the arg in quotes, unless already quoted (see quoted?).
|
30
|
+
def quote(str)
|
31
|
+
quoted?(str) ? str : "\"#{str}\""
|
25
32
|
end
|
26
33
|
|
27
34
|
# Returns true if the str is quoted (either by quotes or apostrophes).
|
@@ -29,15 +36,27 @@ module Linebook
|
|
29
36
|
str =~ /\A".*"\z/ || str =~ /\A'.*'\z/ ? true : false
|
30
37
|
end
|
31
38
|
|
39
|
+
# Encloses the arg in quotes unless the arg is an option or already quoted
|
40
|
+
# (see option? and quoted?).
|
41
|
+
def option_quote(str)
|
42
|
+
option?(str) ? str : quote(str)
|
43
|
+
end
|
44
|
+
|
45
|
+
# Returns true if the str is an option (ie it begins with - or +).
|
46
|
+
def option?(str)
|
47
|
+
c = str[0]
|
48
|
+
c == ?- || c == ?+
|
49
|
+
end
|
50
|
+
|
32
51
|
# Formats a command line command. Arguments are quoted. If the last arg is a
|
33
52
|
# hash, then it will be formatted into options using format_options and
|
34
53
|
# prepended to args.
|
35
|
-
def
|
54
|
+
def command_str(command, *args)
|
36
55
|
opts = args.last.kind_of?(Hash) ? args.pop : {}
|
37
56
|
args.compact!
|
38
|
-
args.collect! {|arg|
|
57
|
+
args.collect! {|arg| option_quote(arg.to_s) }
|
39
58
|
|
40
|
-
args =
|
59
|
+
args = options_str(opts) + args
|
41
60
|
args.unshift(command)
|
42
61
|
args.join(' ')
|
43
62
|
end
|
@@ -56,7 +75,7 @@ module Linebook
|
|
56
75
|
# symbols) such that underscores are converted to dashes, ie :some_key =>
|
57
76
|
# 'some-key'. Note that options are sorted, such that short options appear
|
58
77
|
# after long options, and so should 'win' given typical option processing.
|
59
|
-
def
|
78
|
+
def options_str(opts)
|
60
79
|
options = []
|
61
80
|
|
62
81
|
opts.each do |(key, value)|
|
@@ -82,48 +101,66 @@ module Linebook
|
|
82
101
|
options.sort
|
83
102
|
end
|
84
103
|
|
85
|
-
#
|
104
|
+
# A hash of functions defined for self.
|
86
105
|
def functions
|
87
|
-
@functions ||=
|
106
|
+
@functions ||= {}
|
88
107
|
end
|
89
108
|
|
90
109
|
# Defines a function from the block. The block content is indented and
|
91
|
-
# cleaned up some to make a nice function definition.
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
# function is already defined with a different body.
|
96
|
-
def function(name, body=nil)
|
97
|
-
if body && block_given?
|
98
|
-
raise "define functions with body or block"
|
99
|
-
end
|
100
|
-
|
101
|
-
if body.nil?
|
102
|
-
str = capture_str { indent { yield } }
|
103
|
-
body = "\n#{str.chomp("\n")}\n"
|
104
|
-
end
|
105
|
-
|
106
|
-
function = "#{name}() {#{body}}"
|
110
|
+
# cleaned up some to make a nice function definition.
|
111
|
+
def function(name, method_name=name)
|
112
|
+
str = capture_str { indent { yield(*signature(Proc.new.arity)) } }
|
113
|
+
function = %{#{name}() {\n#{str.chomp("\n")}\n}}
|
107
114
|
|
108
|
-
if
|
109
|
-
|
115
|
+
if function?(name)
|
116
|
+
unless functions[name] == function
|
110
117
|
raise "function already defined: #{name.inspect}"
|
111
118
|
end
|
119
|
+
else
|
120
|
+
functions[name] = function
|
121
|
+
|
122
|
+
if method_name
|
123
|
+
instance_eval %{
|
124
|
+
def self.#{method_name}(*args)
|
125
|
+
execute '#{method_name}', *args
|
126
|
+
chain_proxy
|
127
|
+
end
|
128
|
+
}
|
129
|
+
end
|
112
130
|
end
|
113
131
|
|
114
|
-
functions << function
|
115
132
|
writeln function
|
116
|
-
|
117
133
|
name
|
118
134
|
end
|
119
135
|
|
120
|
-
# Returns true if
|
136
|
+
# Returns true if a function with the given name is defined.
|
121
137
|
def function?(name)
|
122
|
-
|
123
|
-
functions.any? {|func| func.index(declaration) == 0 }
|
138
|
+
functions.has_key?(name)
|
124
139
|
end
|
125
140
|
|
126
|
-
|
141
|
+
# Returns an array of positional variables for use as inputs to a function
|
142
|
+
# block. Splat blocks are supported; the splat expression behaves like $*.
|
143
|
+
def signature(arity)
|
144
|
+
variables = Array.new(arity.abs) {|i| var(i+1) }
|
145
|
+
|
146
|
+
if arity < 0
|
147
|
+
# This works for defaults...
|
148
|
+
# $(shift 1; echo ${*:-NONE})
|
149
|
+
# You can't do this:
|
150
|
+
# ${$(shift 1; echo $*):-NONE}
|
151
|
+
variables[-1] = "$(shift #{arity.abs - 1}; echo $*)"
|
152
|
+
end
|
153
|
+
|
154
|
+
variables
|
155
|
+
end
|
156
|
+
|
157
|
+
def var(name)
|
158
|
+
Variable.new(name)
|
159
|
+
end
|
160
|
+
|
161
|
+
def trailer
|
162
|
+
/(\s*(?:\ncheck_status.*?\n\s*)?)\z/
|
163
|
+
end
|
127
164
|
|
128
165
|
# Adds a redirect to append stdout to a file.
|
129
166
|
def append(path=nil)
|
@@ -137,6 +174,22 @@ module Linebook
|
|
137
174
|
str
|
138
175
|
end
|
139
176
|
|
177
|
+
# Exit from for, while, or until loop.
|
178
|
+
# {[Spec]}[http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_15]
|
179
|
+
def break_()
|
180
|
+
# break
|
181
|
+
#
|
182
|
+
write "break\n"
|
183
|
+
|
184
|
+
chain_proxy
|
185
|
+
end
|
186
|
+
|
187
|
+
def _break_(*args, &block) # :nodoc:
|
188
|
+
str = capture_str { break_(*args, &block) }
|
189
|
+
str.strip!
|
190
|
+
str
|
191
|
+
end
|
192
|
+
|
140
193
|
# Adds a check that ensures the last exit status is as indicated. Note that no
|
141
194
|
# check will be added unless check_status_function is added beforehand.
|
142
195
|
def check_status(expect_status=0, fail_status='$?')
|
@@ -157,9 +210,20 @@ module Linebook
|
|
157
210
|
str
|
158
211
|
end
|
159
212
|
|
160
|
-
#
|
213
|
+
# Defines the check status function.
|
161
214
|
def check_status_function()
|
162
|
-
function
|
215
|
+
function('check_status', nil) do |expected, actual, error, message|
|
216
|
+
message.default = '?'
|
217
|
+
|
218
|
+
if_ actual.ne(expected) do
|
219
|
+
writeln %{echo [#{actual}] #{program_name}:#{message}}
|
220
|
+
exit_ error
|
221
|
+
end
|
222
|
+
|
223
|
+
else_ do
|
224
|
+
return_ actual
|
225
|
+
end
|
226
|
+
end
|
163
227
|
chain_proxy
|
164
228
|
end
|
165
229
|
|
@@ -184,18 +248,80 @@ module Linebook
|
|
184
248
|
str
|
185
249
|
end
|
186
250
|
|
187
|
-
#
|
251
|
+
# Continue for, while, or until loop.
|
252
|
+
# {[Spec]}[http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_17]
|
253
|
+
def continue_()
|
254
|
+
# continue
|
255
|
+
#
|
256
|
+
write "continue\n"
|
257
|
+
|
258
|
+
chain_proxy
|
259
|
+
end
|
260
|
+
|
261
|
+
def _continue_(*args, &block) # :nodoc:
|
262
|
+
str = capture_str { continue_(*args, &block) }
|
263
|
+
str.strip!
|
264
|
+
str
|
265
|
+
end
|
266
|
+
|
267
|
+
# Chains to if_ to make an else-if statement.
|
268
|
+
def elif_(expression)
|
269
|
+
unless match = rewrite(/(\s+)(fi\s*)/)
|
270
|
+
raise "elif_ used outside of if_ statement"
|
271
|
+
end
|
272
|
+
# <%= match[1] %>
|
273
|
+
# elif <%= expression %>
|
274
|
+
# then
|
275
|
+
# <% indent { yield } %>
|
276
|
+
# <%= match[2] %>
|
277
|
+
write(( match[1] ).to_s)
|
278
|
+
write "elif "; write(( expression ).to_s); write "\n"
|
279
|
+
write "then\n"
|
280
|
+
indent { yield }
|
281
|
+
write(( match[2] ).to_s)
|
282
|
+
chain_proxy
|
283
|
+
end
|
284
|
+
|
285
|
+
def _elif_(*args, &block) # :nodoc:
|
286
|
+
str = capture_str { elif_(*args, &block) }
|
287
|
+
str.strip!
|
288
|
+
str
|
289
|
+
end
|
290
|
+
|
291
|
+
# Chains to if_ or unless_ to make an else statement.
|
292
|
+
def else_()
|
293
|
+
unless match = rewrite(/(\s+)(fi\s*)/)
|
294
|
+
raise "else_ used outside of if_ statement"
|
295
|
+
end
|
296
|
+
# <%= match[1] %>
|
297
|
+
# else
|
298
|
+
# <% indent { yield } %>
|
299
|
+
# <%= match[2] %>
|
300
|
+
write(( match[1] ).to_s)
|
301
|
+
write "else\n"
|
302
|
+
indent { yield }
|
303
|
+
write(( match[2] ).to_s)
|
304
|
+
chain_proxy
|
305
|
+
end
|
306
|
+
|
307
|
+
def _else_(*args, &block) # :nodoc:
|
308
|
+
str = capture_str { else_(*args, &block) }
|
309
|
+
str.strip!
|
310
|
+
str
|
311
|
+
end
|
312
|
+
|
313
|
+
# Executes a command and checks the output status. Quotes all non-option args
|
188
314
|
# that aren't already quoted. Accepts a trailing hash which will be transformed
|
189
315
|
# into command line options.
|
190
316
|
def execute(command, *args)
|
191
317
|
if chain?
|
192
|
-
rewrite(
|
318
|
+
rewrite(trailer)
|
193
319
|
write ' | '
|
194
320
|
end
|
195
|
-
# <%=
|
321
|
+
# <%= command_str(command, *args) %>
|
196
322
|
#
|
197
323
|
# <% check_status %>
|
198
|
-
write((
|
324
|
+
write(( command_str(command, *args) ).to_s)
|
199
325
|
write "\n"
|
200
326
|
check_status
|
201
327
|
chain_proxy
|
@@ -207,17 +333,26 @@ module Linebook
|
|
207
333
|
str
|
208
334
|
end
|
209
335
|
|
210
|
-
#
|
211
|
-
|
212
|
-
|
336
|
+
# Cause the shell to exit.
|
337
|
+
# {[Spec]}[http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_21]
|
338
|
+
def exit_(status=nil)
|
339
|
+
# <% if status.nil? %>
|
340
|
+
# exit
|
341
|
+
# <% else %>
|
342
|
+
# exit <%= status %>
|
343
|
+
# <% end %>
|
213
344
|
#
|
214
|
-
|
345
|
+
if status.nil?
|
346
|
+
write "exit\n"
|
347
|
+
else
|
348
|
+
write "exit "; write(( status ).to_s); write "\n"
|
349
|
+
end
|
215
350
|
|
216
351
|
chain_proxy
|
217
352
|
end
|
218
353
|
|
219
|
-
def
|
220
|
-
str = capture_str {
|
354
|
+
def _exit_(*args, &block) # :nodoc:
|
355
|
+
str = capture_str { exit_(*args, &block) }
|
221
356
|
str.strip!
|
222
357
|
str
|
223
358
|
end
|
@@ -240,7 +375,7 @@ module Linebook
|
|
240
375
|
# outdent add '-' before the delimiter
|
241
376
|
# quote quotes the delimiter
|
242
377
|
def heredoc(options={})
|
243
|
-
tail = chain? ? rewrite(
|
378
|
+
tail = chain? ? rewrite(trailer) {|m| write ' '; m[1].lstrip } : nil
|
244
379
|
|
245
380
|
unless options.kind_of?(Hash)
|
246
381
|
options = {:delimiter => options}
|
@@ -255,11 +390,13 @@ module Linebook
|
|
255
390
|
# <%= delimiter %><% end %>
|
256
391
|
#
|
257
392
|
# <%= tail %>
|
393
|
+
#
|
258
394
|
write "<<"; write(( options[:outdent] ? '-' : ' ').to_s); write(( options[:quote] ? "\"#{delimiter}\"" : delimiter ).to_s); outdent(" # :#{delimiter}:") do ; write "\n"
|
259
395
|
yield
|
260
396
|
write(( delimiter ).to_s); end
|
261
397
|
write "\n"
|
262
398
|
write(( tail ).to_s)
|
399
|
+
|
263
400
|
chain_proxy
|
264
401
|
end
|
265
402
|
|
@@ -297,7 +434,7 @@ module Linebook
|
|
297
434
|
source = source.nil? || source.kind_of?(Fixnum) ? source : "#{source} "
|
298
435
|
target = target.nil? || target.kind_of?(Fixnum) ? "&#{target}" : " #{target}"
|
299
436
|
|
300
|
-
match = chain? ? rewrite(
|
437
|
+
match = chain? ? rewrite(trailer) : nil
|
301
438
|
write " #{source}#{redirection}#{target}"
|
302
439
|
write match[1] if match
|
303
440
|
chain_proxy
|
@@ -309,21 +446,45 @@ module Linebook
|
|
309
446
|
str
|
310
447
|
end
|
311
448
|
|
312
|
-
#
|
313
|
-
|
314
|
-
|
315
|
-
#
|
449
|
+
# Return from a function.
|
450
|
+
# {[Spec]}[http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_24]
|
451
|
+
def return_(status=nil)
|
452
|
+
# <% if status.nil? %>
|
453
|
+
# return
|
454
|
+
# <% else %>
|
455
|
+
# return <%= status %>
|
316
456
|
# <% end %>
|
317
457
|
#
|
318
|
-
|
319
|
-
write "
|
458
|
+
if status.nil?
|
459
|
+
write "return\n"
|
460
|
+
else
|
461
|
+
write "return "; write(( status ).to_s); write "\n"
|
320
462
|
end
|
321
463
|
|
322
464
|
chain_proxy
|
323
465
|
end
|
324
466
|
|
325
|
-
def
|
326
|
-
str = capture_str {
|
467
|
+
def _return_(*args, &block) # :nodoc:
|
468
|
+
str = capture_str { return_(*args, &block) }
|
469
|
+
str.strip!
|
470
|
+
str
|
471
|
+
end
|
472
|
+
|
473
|
+
# Write a comment to delimit sections. The comment takes the format:
|
474
|
+
#
|
475
|
+
# #### name ###
|
476
|
+
def section(name="")
|
477
|
+
n = (78 - name.length)/2
|
478
|
+
str = "-" * n
|
479
|
+
# #<%= str %><%= name %><%= str %><%= "-" if name.length % 2 == 1 %>
|
480
|
+
#
|
481
|
+
write "#"; write(( str ).to_s); write(( name ).to_s); write(( str ).to_s); write(( "-" if name.length % 2 == 1 ).to_s); write "\n"
|
482
|
+
|
483
|
+
chain_proxy
|
484
|
+
end
|
485
|
+
|
486
|
+
def _section(*args, &block) # :nodoc:
|
487
|
+
str = capture_str { section(*args, &block) }
|
327
488
|
str.strip!
|
328
489
|
str
|
329
490
|
end
|
@@ -352,19 +513,25 @@ module Linebook
|
|
352
513
|
str
|
353
514
|
end
|
354
515
|
|
355
|
-
#
|
356
|
-
def
|
357
|
-
#
|
358
|
-
#
|
359
|
-
# <%
|
360
|
-
|
361
|
-
|
362
|
-
|
516
|
+
# Executes the block until the expression evaluates to zero.
|
517
|
+
def until_(expression)
|
518
|
+
# until <%= expression %>
|
519
|
+
# do
|
520
|
+
# <% indent { yield } %>
|
521
|
+
# done
|
522
|
+
#
|
523
|
+
#
|
524
|
+
write "until "; write(( expression ).to_s); write "\n"
|
525
|
+
write "do\n"
|
526
|
+
indent { yield }
|
527
|
+
write "done\n"
|
528
|
+
write "\n"
|
529
|
+
|
363
530
|
chain_proxy
|
364
531
|
end
|
365
532
|
|
366
|
-
def
|
367
|
-
str = capture_str {
|
533
|
+
def _until_(*args, &block) # :nodoc:
|
534
|
+
str = capture_str { until_(*args, &block) }
|
368
535
|
str.strip!
|
369
536
|
str
|
370
537
|
end
|
@@ -385,6 +552,29 @@ module Linebook
|
|
385
552
|
str.strip!
|
386
553
|
str
|
387
554
|
end
|
555
|
+
|
556
|
+
# Executes the block while the expression evaluates to zero.
|
557
|
+
def while_(expression)
|
558
|
+
# while <%= expression %>
|
559
|
+
# do
|
560
|
+
# <% indent { yield } %>
|
561
|
+
# done
|
562
|
+
#
|
563
|
+
#
|
564
|
+
write "while "; write(( expression ).to_s); write "\n"
|
565
|
+
write "do\n"
|
566
|
+
indent { yield }
|
567
|
+
write "done\n"
|
568
|
+
write "\n"
|
569
|
+
|
570
|
+
chain_proxy
|
571
|
+
end
|
572
|
+
|
573
|
+
def _while_(*args, &block) # :nodoc:
|
574
|
+
str = capture_str { while_(*args, &block) }
|
575
|
+
str.strip!
|
576
|
+
str
|
577
|
+
end
|
388
578
|
end
|
389
579
|
end
|
390
580
|
end
|