0 0 1
default
Jean-Francois Pieronne - 4 years ago 2016-11-30 15:39:06
jf.pieronne@laposte.net
Docs/tsshbatch.html initial version
1 file changed with 1897 insertions and 0 deletions:
↑ Collapse Diff ↑
 
new file 100644
1
 
<?xml version="1.0" encoding="utf-8" ?>
2
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3
 
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
4
 
<head>
5
 
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
6
 
<meta name="generator" content="Docutils 0.12: http://docutils.sourceforge.net/" />
7
 
<title></title>
8
 
<style type="text/css">
9
 

	
10
 
/*
11
 
:Author: David Goodger (goodger@python.org)
12
 
:Id: $Id: html4css1.css 7614 2013-02-21 15:55:51Z milde $
13
 
:Copyright: This stylesheet has been placed in the public domain.
14
 

	
15
 
Default cascading style sheet for the HTML output of Docutils.
16
 

	
17
 
See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to
18
 
customize this style sheet.
19
 
*/
20
 

	
21
 
/* used to remove borders from tables and images */
22
 
.borderless, table.borderless td, table.borderless th {
23
 
  border: 0 }
24
 

	
25
 
table.borderless td, table.borderless th {
26
 
  /* Override padding for "table.docutils td" with "! important".
27
 
     The right padding separates the table cells. */
28
 
  padding: 0 0.5em 0 0 ! important }
29
 

	
30
 
.first {
31
 
  /* Override more specific margin styles with "! important". */
32
 
  margin-top: 0 ! important }
33
 

	
34
 
.last, .with-subtitle {
35
 
  margin-bottom: 0 ! important }
36
 

	
37
 
.hidden {
38
 
  display: none }
39
 

	
40
 
a.toc-backref {
41
 
  text-decoration: none ;
42
 
  color: black }
43
 

	
44
 
blockquote.epigraph {
45
 
  margin: 2em 5em ; }
46
 

	
47
 
dl.docutils dd {
48
 
  margin-bottom: 0.5em }
49
 

	
50
 
object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] {
51
 
  overflow: hidden;
52
 
}
53
 

	
54
 
/* Uncomment (and remove this text!) to get bold-faced definition list terms
55
 
dl.docutils dt {
56
 
  font-weight: bold }
57
 
*/
58
 

	
59
 
div.abstract {
60
 
  margin: 2em 5em }
61
 

	
62
 
div.abstract p.topic-title {
63
 
  font-weight: bold ;
64
 
  text-align: center }
65
 

	
66
 
div.admonition, div.attention, div.caution, div.danger, div.error,
67
 
div.hint, div.important, div.note, div.tip, div.warning {
68
 
  margin: 2em ;
69
 
  border: medium outset ;
70
 
  padding: 1em }
71
 

	
72
 
div.admonition p.admonition-title, div.hint p.admonition-title,
73
 
div.important p.admonition-title, div.note p.admonition-title,
74
 
div.tip p.admonition-title {
75
 
  font-weight: bold ;
76
 
  font-family: sans-serif }
77
 

	
78
 
div.attention p.admonition-title, div.caution p.admonition-title,
79
 
div.danger p.admonition-title, div.error p.admonition-title,
80
 
div.warning p.admonition-title, .code .error {
81
 
  color: red ;
82
 
  font-weight: bold ;
83
 
  font-family: sans-serif }
84
 

	
85
 
/* Uncomment (and remove this text!) to get reduced vertical space in
86
 
   compound paragraphs.
87
 
div.compound .compound-first, div.compound .compound-middle {
88
 
  margin-bottom: 0.5em }
89
 

	
90
 
div.compound .compound-last, div.compound .compound-middle {
91
 
  margin-top: 0.5em }
92
 
*/
93
 

	
94
 
div.dedication {
95
 
  margin: 2em 5em ;
96
 
  text-align: center ;
97
 
  font-style: italic }
98
 

	
99
 
div.dedication p.topic-title {
100
 
  font-weight: bold ;
101
 
  font-style: normal }
102
 

	
103
 
div.figure {
104
 
  margin-left: 2em ;
105
 
  margin-right: 2em }
106
 

	
107
 
div.footer, div.header {
108
 
  clear: both;
109
 
  font-size: smaller }
110
 

	
111
 
div.line-block {
112
 
  display: block ;
113
 
  margin-top: 1em ;
114
 
  margin-bottom: 1em }
115
 

	
116
 
div.line-block div.line-block {
117
 
  margin-top: 0 ;
118
 
  margin-bottom: 0 ;
119
 
  margin-left: 1.5em }
120
 

	
121
 
div.sidebar {
122
 
  margin: 0 0 0.5em 1em ;
123
 
  border: medium outset ;
124
 
  padding: 1em ;
125
 
  background-color: #ffffee ;
126
 
  width: 40% ;
127
 
  float: right ;
128
 
  clear: right }
129
 

	
130
 
div.sidebar p.rubric {
131
 
  font-family: sans-serif ;
132
 
  font-size: medium }
133
 

	
134
 
div.system-messages {
135
 
  margin: 5em }
136
 

	
137
 
div.system-messages h1 {
138
 
  color: red }
139
 

	
140
 
div.system-message {
141
 
  border: medium outset ;
142
 
  padding: 1em }
143
 

	
144
 
div.system-message p.system-message-title {
145
 
  color: red ;
146
 
  font-weight: bold }
147
 

	
148
 
div.topic {
149
 
  margin: 2em }
150
 

	
151
 
h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
152
 
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
153
 
  margin-top: 0.4em }
154
 

	
155
 
h1.title {
156
 
  text-align: center }
157
 

	
158
 
h2.subtitle {
159
 
  text-align: center }
160
 

	
161
 
hr.docutils {
162
 
  width: 75% }
163
 

	
164
 
img.align-left, .figure.align-left, object.align-left {
165
 
  clear: left ;
166
 
  float: left ;
167
 
  margin-right: 1em }
168
 

	
169
 
img.align-right, .figure.align-right, object.align-right {
170
 
  clear: right ;
171
 
  float: right ;
172
 
  margin-left: 1em }
173
 

	
174
 
img.align-center, .figure.align-center, object.align-center {
175
 
  display: block;
176
 
  margin-left: auto;
177
 
  margin-right: auto;
178
 
}
179
 

	
180
 
.align-left {
181
 
  text-align: left }
182
 

	
183
 
.align-center {
184
 
  clear: both ;
185
 
  text-align: center }
186
 

	
187
 
.align-right {
188
 
  text-align: right }
189
 

	
190
 
/* reset inner alignment in figures */
191
 
div.align-right {
192
 
  text-align: inherit }
193
 

	
194
 
/* div.align-center * { */
195
 
/*   text-align: left } */
196
 

	
197
 
ol.simple, ul.simple {
198
 
  margin-bottom: 1em }
199
 

	
200
 
ol.arabic {
201
 
  list-style: decimal }
202
 

	
203
 
ol.loweralpha {
204
 
  list-style: lower-alpha }
205
 

	
206
 
ol.upperalpha {
207
 
  list-style: upper-alpha }
208
 

	
209
 
ol.lowerroman {
210
 
  list-style: lower-roman }
211
 

	
212
 
ol.upperroman {
213
 
  list-style: upper-roman }
214
 

	
215
 
p.attribution {
216
 
  text-align: right ;
217
 
  margin-left: 50% }
218
 

	
219
 
p.caption {
220
 
  font-style: italic }
221
 

	
222
 
p.credits {
223
 
  font-style: italic ;
224
 
  font-size: smaller }
225
 

	
226
 
p.label {
227
 
  white-space: nowrap }
228
 

	
229
 
p.rubric {
230
 
  font-weight: bold ;
231
 
  font-size: larger ;
232
 
  color: maroon ;
233
 
  text-align: center }
234
 

	
235
 
p.sidebar-title {
236
 
  font-family: sans-serif ;
237
 
  font-weight: bold ;
238
 
  font-size: larger }
239
 

	
240
 
p.sidebar-subtitle {
241
 
  font-family: sans-serif ;
242
 
  font-weight: bold }
243
 

	
244
 
p.topic-title {
245
 
  font-weight: bold }
246
 

	
247
 
pre.address {
248
 
  margin-bottom: 0 ;
249
 
  margin-top: 0 ;
250
 
  font: inherit }
251
 

	
252
 
pre.literal-block, pre.doctest-block, pre.math, pre.code {
253
 
  margin-left: 2em ;
254
 
  margin-right: 2em }
255
 

	
256
 
pre.code .ln { color: grey; } /* line numbers */
257
 
pre.code, code { background-color: #eeeeee }
258
 
pre.code .comment, code .comment { color: #5C6576 }
259
 
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
260
 
pre.code .literal.string, code .literal.string { color: #0C5404 }
261
 
pre.code .name.builtin, code .name.builtin { color: #352B84 }
262
 
pre.code .deleted, code .deleted { background-color: #DEB0A1}
263
 
pre.code .inserted, code .inserted { background-color: #A3D289}
264
 

	
265
 
span.classifier {
266
 
  font-family: sans-serif ;
267
 
  font-style: oblique }
268
 

	
269
 
span.classifier-delimiter {
270
 
  font-family: sans-serif ;
271
 
  font-weight: bold }
272
 

	
273
 
span.interpreted {
274
 
  font-family: sans-serif }
275
 

	
276
 
span.option {
277
 
  white-space: nowrap }
278
 

	
279
 
span.pre {
280
 
  white-space: pre }
281
 

	
282
 
span.problematic {
283
 
  color: red }
284
 

	
285
 
span.section-subtitle {
286
 
  /* font-size relative to parent (h1..h6 element) */
287
 
  font-size: 80% }
288
 

	
289
 
table.citation {
290
 
  border-left: solid 1px gray;
291
 
  margin-left: 1px }
292
 

	
293
 
table.docinfo {
294
 
  margin: 2em 4em }
295
 

	
296
 
table.docutils {
297
 
  margin-top: 0.5em ;
298
 
  margin-bottom: 0.5em }
299
 

	
300
 
table.footnote {
301
 
  border-left: solid 1px black;
302
 
  margin-left: 1px }
303
 

	
304
 
table.docutils td, table.docutils th,
305
 
table.docinfo td, table.docinfo th {
306
 
  padding-left: 0.5em ;
307
 
  padding-right: 0.5em ;
308
 
  vertical-align: top }
309
 

	
310
 
table.docutils th.field-name, table.docinfo th.docinfo-name {
311
 
  font-weight: bold ;
312
 
  text-align: left ;
313
 
  white-space: nowrap ;
314
 
  padding-left: 0 }
315
 

	
316
 
/* "booktabs" style (no vertical lines) */
317
 
table.docutils.booktabs {
318
 
  border: 0px;
319
 
  border-top: 2px solid;
320
 
  border-bottom: 2px solid;
321
 
  border-collapse: collapse;
322
 
}
323
 
table.docutils.booktabs * {
324
 
  border: 0px;
325
 
}
326
 
table.docutils.booktabs th {
327
 
  border-bottom: thin solid;
328
 
  text-align: left;
329
 
}
330
 

	
331
 
h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
332
 
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
333
 
  font-size: 100% }
334
 

	
335
 
ul.auto-toc {
336
 
  list-style-type: none }
337
 

	
338
 
</style>
339
 
</head>
340
 
<body>
341
 
<div class="document">
342
 

	
343
 

	
344
 
<div class="contents topic" id="contents">
345
 
<p class="topic-title first">Contents</p>
346
 
<ul>
347
 
<li><p class="first"><a class="reference internal" href="#name" id="id1">NAME</a></p>
348
 
</li>
349
 
<li><p class="first"><a class="reference internal" href="#synopsis" id="id2">SYNOPSIS</a></p>
350
 
</li>
351
 
<li><p class="first"><a class="reference internal" href="#description" id="id3">DESCRIPTION</a></p>
352
 
</li>
353
 
<li><p class="first"><a class="reference internal" href="#options" id="id4">OPTIONS</a></p>
354
 
</li>
355
 
<li><p class="first"><a class="reference internal" href="#environment" id="id5">ENVIRONMENT</a></p>
356
 
</li>
357
 
<li><p class="first"><a class="reference internal" href="#ssh-configuration-file-processing" id="id6">SSH CONFIGURATION FILE PROCESSING</a></p>
358
 
</li>
359
 
<li><p class="first"><a class="reference internal" href="#managing-inventory-host-files" id="id7">MANAGING INVENTORY: HOST FILES</a></p>
360
 
</li>
361
 
<li><p class="first"><a class="reference internal" href="#managing-jobs-command-files" id="id8">MANAGING JOBS: COMMAND FILES</a></p>
362
 
</li>
363
 
<li><p class="first"><a class="reference internal" href="#searching-your-host-and-command-files" id="id9">SEARCHING YOUR HOST AND COMMAND FILES</a></p>
364
 
</li>
365
 
<li><p class="first"><a class="reference internal" href="#features-and-use-cases" id="id10">FEATURES AND USE CASES</a></p>
366
 
<ul>
367
 
<li><p class="first"><a class="reference internal" href="#different-ways-to-specify-targeted-hostnames" id="id11">Different Ways To Specify Targeted Hostnames</a></p>
368
 
</li>
369
 
<li><p class="first"><a class="reference internal" href="#authentication-using-name-and-password" id="id12">Authentication Using Name And Password</a></p>
370
 
</li>
371
 
<li><p class="first"><a class="reference internal" href="#authentication-using-key-exchange" id="id13">Authentication Using Key Exchange</a></p>
372
 
</li>
373
 
<li><p class="first"><a class="reference internal" href="#executing-a-sudo-command" id="id14">Executing A <tt class="docutils literal">sudo</tt> Command</a></p>
374
 
</li>
375
 
<li><p class="first"><a class="reference internal" href="#precedence-of-authentication-options" id="id15">Precedence Of Authentication Options</a></p>
376
 
</li>
377
 
<li><p class="first"><a class="reference internal" href="#file-transfers" id="id16">File Transfers</a></p>
378
 
</li>
379
 
<li><p class="first"><a class="reference internal" href="#commenting" id="id17">Commenting</a></p>
380
 
</li>
381
 
<li><p class="first"><a class="reference internal" href="#includes" id="id18">Includes</a></p>
382
 
</li>
383
 
<li><p class="first"><a class="reference internal" href="#search-paths" id="id19">Search Paths</a></p>
384
 
</li>
385
 
<li><p class="first"><a class="reference internal" href="#an-overview-of-variables" id="id20">An Overview Of Variables</a></p>
386
 
</li>
387
 
<li><p class="first"><a class="reference internal" href="#types-of-variables" id="id21">Types Of Variables</a></p>
388
 
</li>
389
 
<li><p class="first"><a class="reference internal" href="#where-and-when-do-variables-get-processed" id="id22">Where And When Do Variables Get Processed?</a></p>
390
 
</li>
391
 
<li><p class="first"><a class="reference internal" href="#global-variables" id="id23">Global Variables</a></p>
392
 
</li>
393
 
<li><p class="first"><a class="reference internal" href="#local-variables" id="id24">Local Variables</a></p>
394
 
</li>
395
 
<li><p class="first"><a class="reference internal" href="#execution-variables" id="id25">Execution Variables</a></p>
396
 
</li>
397
 
<li><p class="first"><a class="reference internal" href="#builtin-variables" id="id26">Builtin Variables</a></p>
398
 
</li>
399
 
<li><p class="first"><a class="reference internal" href="#using-builtin-variables" id="id27">Using Builtin Variables</a></p>
400
 
</li>
401
 
<li><p class="first"><a class="reference internal" href="#noise-levels" id="id28">Noise Levels</a></p>
402
 
</li>
403
 
</ul>
404
 
</li>
405
 
<li><p class="first"><a class="reference internal" href="#other" id="id29">OTHER</a></p>
406
 
</li>
407
 
<li><p class="first"><a class="reference internal" href="#bugs-and-misfeatures" id="id30">BUGS AND MISFEATURES</a></p>
408
 
</li>
409
 
<li><p class="first"><a class="reference internal" href="#other-similar-products" id="id31">OTHER, SIMILAR PRODUCTS</a></p>
410
 
</li>
411
 
<li><p class="first"><a class="reference internal" href="#copyright-and-licensing" id="id32">COPYRIGHT AND LICENSING</a></p>
412
 
</li>
413
 
<li><p class="first"><a class="reference internal" href="#author" id="id33">AUTHOR</a></p>
414
 
</li>
415
 
<li><p class="first"><a class="reference internal" href="#document-revision-information" id="id34">DOCUMENT REVISION INFORMATION</a></p>
416
 
</li>
417
 
</ul>
418
 
</div>
419
 
<div class="section" id="name">
420
 
<h1><a class="toc-backref" href="#id1">NAME</a></h1>
421
 
<p><strong>tsshbatch</strong> - Run Commands On Batches Of Machines</p>
422
 
<div class="warning">
423
 
<p class="first admonition-title">Warning</p>
424
 
<p><tt class="docutils literal">tsshbatch</tt> is a powerful tool for automating activities
425
 
on many servers at a time.  This also gives you to power
426
 
<em>to make many mistakes at a time!</em> This is especially
427
 
true if you have <tt class="docutils literal">sudo</tt> privilege promotion
428
 
capabilities on the systems in your care.  <em>So be careful
429
 
out there!</em></p>
430
 
<p>We therefore STRONGLY recommend you do the following
431
 
things to mitigate this risk:</p>
432
 
<blockquote class="last">
433
 
<ul>
434
 
<li><p class="first">Read This Fine Manual from beginning to end.</p>
435
 
</li>
436
 
<li><p class="first">Practice using <tt class="docutils literal">tsshbatch</tt> on test machines or
437
 
VMs that can easily be recovered or reimaged if you
438
 
break someting.</p>
439
 
</li>
440
 
<li><p class="first">Make heavy use of test mode (which is the default)
441
 
to see what the program <em>would</em> do if it actually
442
 
ran in execution mode.</p>
443
 
</li>
444
 
</ul>
445
 
</blockquote>
446
 
</div>
447
 
</div>
448
 
<div class="section" id="synopsis">
449
 
<h1><a class="toc-backref" href="#id2">SYNOPSIS</a></h1>
450
 
<pre class="literal-block">
451
 
tsshbatch.py [-EKLNSTWaehkqrstvxy -G 'file dest' -P 'file dest' -f cmdfile -l logfile -n name -p pw ] -H 'host ..' -i 'hostfile ...' [command arg ... ]
452
 
</pre>
453
 
</div>
454
 
<div class="section" id="description">
455
 
<h1><a class="toc-backref" href="#id3">DESCRIPTION</a></h1>
456
 
<p><tt class="docutils literal">tsshbatch</tt> is a tool to enable you to issue a command to many
457
 
hosts without having to log into each one separately.  When writing
458
 
scripts, this overcomes the <tt class="docutils literal">ssh</tt> limitation of not being able to
459
 
specify the password on the command line.</p>
460
 
<p>You can also use <tt class="docutils literal">tsshbatch</tt> to <tt class="docutils literal">GET</tt> and <tt class="docutils literal">PUT</tt> files
461
 
from- and to many hosts at once.</p>
462
 
<p><tt class="docutils literal">tsshbatch</tt> also understands basic <tt class="docutils literal">sudo</tt> syntax and can be used
463
 
to access a host, <tt class="docutils literal">sudo</tt> a command, and then exit.</p>
464
 
<p><tt class="docutils literal">tsshbatch</tt> thus allows you to write complex, hands-off scripts that
465
 
issue commands to many hosts without the tedium of manual login and
466
 
<tt class="docutils literal">sudo</tt> promotion.  System administrators, especially, will find this
467
 
helpful when working in large server farms.</p>
468
 
</div>
469
 
<div class="section" id="options">
470
 
<h1><a class="toc-backref" href="#id4">OPTIONS</a></h1>
471
 
<p><tt class="docutils literal">tsshbatch</tt> supports a variety of options which can be specified
472
 
on either the command line or in the <tt class="docutils literal">$TSSHBATCH</tt> environment
473
 
variable:</p>
474
 
<blockquote>
475
 
<table class="docutils option-list" frame="void" rules="none">
476
 
<col class="option" />
477
 
<col class="description" />
478
 
<tbody valign="top">
479
 
<tr><td class="option-group">
480
 
<kbd><span class="option">-B</span></kbd></td>
481
 
<td>Print start, stop, and elapsed execution time
482
 
statistics.  This does not include any time
483
 
spent for interactive prompting and response,
484
 
but reflects actual program runtime.  (Default: Off)</td></tr>
485
 
<tr><td class="option-group">
486
 
<kbd><span class="option">-C <var>configfile</var></span></kbd></td>
487
 
<td>Specify the location of the ssh configuration
488
 
file.  (Default: <tt class="docutils literal"><span class="pre">~/.ssh/config</span></tt>)</td></tr>
489
 
<tr><td class="option-group">
490
 
<kbd><span class="option">-E</span></kbd></td>
491
 
<td><p class="first">Normally, <tt class="docutils literal">tsshbatch</tt> writes it's own errors
492
 
to <tt class="docutils literal">stderr</tt>.  It also writes the <tt class="docutils literal">stderr</tt>
493
 
output from each host it contacts to the local
494
 
shell's <tt class="docutils literal">stderr</tt> (unless the <tt class="docutils literal"><span class="pre">-e</span></tt> option has
495
 
been selected).</p>
496
 
<p class="last">The <tt class="docutils literal"><span class="pre">-E</span></tt> option redirects any such <tt class="docutils literal">tsshbatch</tt>
497
 
output intended for <tt class="docutils literal">stderr</tt> to <tt class="docutils literal">stdout</tt>
498
 
instead.  This avoids the need to do things like
499
 
<tt class="docutils literal"><span class="pre">2&gt;&amp;1</span> | <span class="pre">...`</span> on the command line when you want to
500
 
pipe all ``tsshbatch</tt> output to another program.</p>
501
 
</td></tr>
502
 
<tr><td class="option-group">
503
 
<kbd><span class="option">-F <var>strings</var></span></kbd></td>
504
 
<td><p class="first">This will examine every file on the host- or
505
 
command paths, looking for matching strings within
506
 
these files.  Matches will report the file name,
507
 
the location within the file, and the line
508
 
containing any of the specified strings.</p>
509
 
<p>This is a simple, case-insensitive string literal
510
 
match and does not support regular expressions.</p>
511
 
<p class="last">This is handy when you're looking for a host name
512
 
or command string, say like, <tt class="docutils literal">sudo</tt> and you don't
513
 
want to have to manually go through all your
514
 
support files.</p>
515
 
</td></tr>
516
 
<tr><td class="option-group">
517
 
<kbd><span class="option">-K</span></kbd></td>
518
 
<td>Force prompting for passwords.  This is used
519
 
to override a prior <tt class="docutils literal"><span class="pre">-k</span></tt> argument.</td></tr>
520
 
<tr><td class="option-group">
521
 
<kbd><span class="option">-G <var>spec</var></span></kbd></td>
522
 
<td><p class="first">GET file on host and write local dest directory.
523
 
<tt class="docutils literal">spec</tt> is a quoted pair of strings.  The first
524
 
specifies the path of the source file (on the
525
 
remote machine) to copy.  The second, specifies
526
 
the destination <em>directory</em> (on the local
527
 
machine):</p>
528
 
<pre class="literal-block">
529
 
tsshbatch.py -G &quot;/foo/bar/baz /tmp&quot; -i hostlist
530
 
</pre>
531
 
<p class="last">This copies <tt class="docutils literal">/foo/bar/baz</tt> from every machine in
532
 
host file to the local <tt class="docutils literal">/tmp/</tt> directory.
533
 
Since all the files have the same name, they would
534
 
overwrite each other if copied into the same
535
 
directory.  So, <tt class="docutils literal">tsshbatch</tt> prepends the string
536
 
<tt class="docutils literal">hostname-</tt> to the name of each file it saves
537
 
locally.</p>
538
 
</td></tr>
539
 
<tr><td class="option-group">
540
 
<kbd><span class="option">-H <var>hostlist</var></span></kbd></td>
541
 
<td><p class="first">List of hosts on which to run the command.  This should
542
 
be enclosed in <em>quotes</em> so that the list of hosts
543
 
is handed to the -H option as a single argument:</p>
544
 
<pre class="literal-block">
545
 
-H 'host1 host2 host3'
546
 
</pre>
547
 
<p class="last">This option may appear on the command line multiple
548
 
times.  The hosts will be processed in the order
549
 
in which they appeared on the command line.</p>
550
 
</td></tr>
551
 
<tr><td class="option-group">
552
 
<kbd><span class="option">-L</span></kbd></td>
553
 
<td>List names of all (if any) host- and command files
554
 
found on their respective search paths.  These are
555
 
listed in the order they are found on those paths.</td></tr>
556
 
<tr><td class="option-group">
557
 
<kbd><span class="option">-N</span></kbd></td>
558
 
<td>Force interactive username dialog.  This cancels
559
 
any previous request for key exchange authentication.</td></tr>
560
 
<tr><td class="option-group">
561
 
<kbd><span class="option">-P <var>spec</var></span></kbd></td>
562
 
<td><p class="first">PUT file from local machine to remote machine destination
563
 
directory.  <tt class="docutils literal">spec</tt> is a quoted pair of strings.
564
 
The first specifies the path of the source file (on
565
 
the local machine) to copy.  The second, specifies
566
 
the destination <em>directory</em> (on the remote machine):</p>
567
 
<pre class="literal-block">
568
 
tsshbatch.py -P &quot;/foo/bar/baz /tmp&quot; -i hostlist
569
 
</pre>
570
 
<p class="last">This copies <tt class="docutils literal">/foo/bar/baz</tt> on the local
571
 
machine to <tt class="docutils literal">/tmp/</tt> on every host in  <tt class="docutils literal">hostlist</tt>.</p>
572
 
</td></tr>
573
 
<tr><td class="option-group">
574
 
<kbd><span class="option">-S</span></kbd></td>
575
 
<td>Force prompting for <tt class="docutils literal">sudo</tt> password.</td></tr>
576
 
<tr><td class="option-group">
577
 
<kbd><span class="option">-T <var>seconds</var></span></kbd></td>
578
 
<td>Set timeout for ssh connection attempts. (Default: 15 seconds)</td></tr>
579
 
<tr><td class="option-group">
580
 
<kbd><span class="option">-V <var>strings</var></span></kbd></td>
581
 
<td>Similar to the <tt class="docutils literal"><span class="pre">-F</span></tt> command but with the inverse logic.
582
 
Reports the names of all host- and command files that
583
 
do not contain any of the specified strings.</td></tr>
584
 
<tr><td class="option-group">
585
 
<kbd><span class="option">-W</span></kbd></td>
586
 
<td><p class="first">Print out a single line list of the inventory that would
587
 
be processed and exit. (Test mode only - Ignored in
588
 
execution mode.)</p>
589
 
<p>This allows you to embed <tt class="docutils literal">tsshbatch</tt> in external
590
 
shell scripts like this:</p>
591
 
<pre class="literal-block">
592
 
for server in $(tsshbatch.py -i devserverlist -i uatserverlist -W)
593
 
do
594
 
  ssh $server
595
 
done
596
 
</pre>
597
 
<p class="last">Why?  Because tsshbatch has lots of powerful ways
598
 
to maintain inventories of hosts and combine them
599
 
through includes and multiple command line
600
 
arguments.  The <tt class="docutils literal"><span class="pre">-W</span></tt> option makes it convenient for
601
 
external programs to make use of those inventory
602
 
features.</p>
603
 
</td></tr>
604
 
<tr><td class="option-group">
605
 
<kbd><span class="option">-a</span></kbd></td>
606
 
<td>Don't abort program after failed file transfers.
607
 
Continue to next transfer attempt.  (Default: Abort)</td></tr>
608
 
<tr><td class="option-group">
609
 
<kbd><span class="option">-b</span></kbd></td>
610
 
<td>Don't abort program after failed <tt class="docutils literal">sudo</tt> command.  Normally, any
611
 
<tt class="docutils literal">sudo</tt> failure causes immediate program termination.  This
612
 
switch tells <tt class="docutils literal">tsshbatch</tt> to continue processing on the
613
 
next host even if such a failure occurs.  This allows
614
 
processing to continue for those hosts where <tt class="docutils literal">sudo</tt> does
615
 
work correctly.  This is helpful in large environments where
616
 
<tt class="docutils literal">sudo</tt> is either improperly configured on some hosts or
617
 
has a different password.  This can also be used to discover
618
 
where <tt class="docutils literal">sudo</tt> does- and does not work correctly.</td></tr>
619
 
<tr><td class="option-group">
620
 
<kbd><span class="option">-e</span></kbd></td>
621
 
<td>Don't report remote host <tt class="docutils literal">stderr</tt> output.</td></tr>
622
 
<tr><td class="option-group">
623
 
<kbd><span class="option">-f <var>cmdfile</var></span></kbd></td>
624
 
<td>Read commands from a file.  This file can be commented
625
 
freely with the <tt class="docutils literal">#</tt> character.  Leading- and
626
 
trailing whitespace on a line are ignored.</td></tr>
627
 
<tr><td class="option-group">
628
 
<kbd><span class="option">-h</span></kbd></td>
629
 
<td>Print help information.</td></tr>
630
 
<tr><td class="option-group">
631
 
<kbd><span class="option">-i <var>hostfiles</var></span></kbd></td>
632
 
<td><p class="first">Specify which files to read to get a list of desired
633
 
hosts to target.  This option may be repeated on the
634
 
command line and may also be followed with a quoted
635
 
list of such files.  The following are equivalent:</p>
636
 
<pre class="literal-block">
637
 
tsshbatch.py -i devservers -i uatservers ...
638
 

	
639
 
tsstbatch.py -i &quot;devservers uatservers&quot; ...
640
 
</pre>
641
 
<p class="last">The <tt class="docutils literal"><span class="pre">-H</span></tt> and <tt class="docutils literal"><span class="pre">-i</span></tt> options can be freely
642
 
combined and repated on the command line to create
643
 
custom host lists made up of both known inventory
644
 
and specific, individual hosts.</p>
645
 
</td></tr>
646
 
<tr><td class="option-group">
647
 
<kbd><span class="option">-k</span></kbd></td>
648
 
<td>Use ssh keys instead of name/password credentials.</td></tr>
649
 
<tr><td class="option-group">
650
 
<kbd><span class="option">-l <var>logfile</var></span></kbd></td>
651
 
<td>Log diagnostic output to <tt class="docutils literal">logfile</tt>. (Default: <tt class="docutils literal">/dev/null</tt>)</td></tr>
652
 
<tr><td class="option-group">
653
 
<kbd><span class="option">-n <var>name</var></span></kbd></td>
654
 
<td>Login name to use.</td></tr>
655
 
<tr><td class="option-group">
656
 
<kbd><span class="option">-p <var>pw</var></span></kbd></td>
657
 
<td>Password to use when logging in and/or doing <tt class="docutils literal">sudo</tt>.</td></tr>
658
 
<tr><td class="option-group">
659
 
<kbd><span class="option">-q</span></kbd></td>
660
 
<td>Quiet mode - produce less noisy output.  Turns off <tt class="docutils literal"><span class="pre">-y</span></tt>.</td></tr>
661
 
<tr><td class="option-group">
662
 
<kbd><span class="option">-r</span></kbd></td>
663
 
<td>Suppress reporting of start/stop statistics. This
664
 
allows you to make statistics reporting the
665
 
default, say via the <tt class="docutils literal">$TSSHBATCH</tt> environment
666
 
variable, but override it when you need to.</td></tr>
667
 
<tr><td class="option-group">
668
 
<kbd><span class="option">-s</span></kbd></td>
669
 
<td>Silence all program noise - only return command output.
670
 
Applies only to command operations.  File transfer
671
 
and error reporting, generally, are unaffected.</td></tr>
672
 
<tr><td class="option-group">
673
 
<kbd><span class="option">-t</span></kbd></td>
674
 
<td>Test mode: Only show what <em>would</em> be done but don't
675
 
actually do it.  This also prints diagnostic
676
 
information about any variable definitions, the list
677
 
of hosts, any <tt class="docutils literal">GET</tt> and <tt class="docutils literal">PUT</tt> requests, and final
678
 
command strings after all variable substitutions have
679
 
been applied.  This is the default program behavior.</td></tr>
680
 
<tr><td class="option-group">
681
 
<kbd><span class="option">-v</span></kbd></td>
682
 
<td>Print detailed program version information and exit.</td></tr>
683
 
<tr><td class="option-group">
684
 
<kbd><span class="option">-x</span></kbd></td>
685
 
<td>Override any previous <tt class="docutils literal"><span class="pre">-t</span></tt> specifications and
686
 
actually execute the commands.  This is useful
687
 
if you want to put <tt class="docutils literal"><span class="pre">-t</span></tt> in the <tt class="docutils literal">$TSSHBATCH</tt>
688
 
environment variable so that the default is
689
 
always run the program in test mode.  Then, when
690
 
you're ready to actually run commands, you can
691
 
override it with <tt class="docutils literal"><span class="pre">-x</span></tt> on the command line.</td></tr>
692
 
<tr><td class="option-group">
693
 
<kbd><span class="option">-y</span></kbd></td>
694
 
<td>Turn on 'noisy' reporting for additional detail on
695
 
every line, instead of just at the top of the
696
 
<tt class="docutils literal">stdout</tt> and <tt class="docutils literal">stderr</tt> reporting.  This is
697
 
helpful when you are filtering the output through
698
 
something like <tt class="docutils literal">grep</tt> that only returns matching
699
 
lines and thus no context information.  Turns off <tt class="docutils literal"><span class="pre">-q</span></tt>.</td></tr>
700
 
</tbody>
701
 
</table>
702
 
</blockquote>
703
 
<p>The last entry on the command line is optional and defines a command
704
 
to run.  <tt class="docutils literal">tsshbatch</tt> will attempt to execute it on every host you've
705
 
specified either via <tt class="docutils literal"><span class="pre">-H</span></tt> or a host file:</p>
706
 
<pre class="literal-block">
707
 
tsshbatch.py -Hmyhost ls -al /etc
708
 
</pre>
709
 
<p>This will do a <tt class="docutils literal">ls <span class="pre">-al</span> /etc</tt> on <tt class="docutils literal">myhost</tt>.</p>
710
 
<p>Be careful when using metacharacters like <tt class="docutils literal">&amp;&amp;, &lt;&lt;, &gt;&gt;, &lt;, &gt;</tt> and so
711
 
on in your commands.  You have to escape and quote them properly or
712
 
your local shell will interfere with them being properly conveyed to
713
 
the remote machine.</p>
714
 
<p><tt class="docutils literal">tsshbatch</tt> does all the <tt class="docutils literal">GETs</tt>, then all the <tt class="docutils literal">PUTs</tt> before
715
 
attempting to do any command processing.  If no <tt class="docutils literal">GETs</tt>, <tt class="docutils literal">PUTs</tt>, or
716
 
commands have been specified, <tt class="docutils literal">tsshbatch</tt> will exit silently, since
717
 
&quot;nothing to do&quot; really isn't an error.</p>
718
 
</div>
719
 
<div class="section" id="environment">
720
 
<h1><a class="toc-backref" href="#id5">ENVIRONMENT</a></h1>
721
 
<p><tt class="docutils literal">tsshbatch</tt> respects the <tt class="docutils literal">$TSSHBATCH</tt> environment variable.  You
722
 
may set this variable with any options above you commonly use to avoid
723
 
having to key them in each time you run the program.  For example:</p>
724
 
<pre class="literal-block">
725
 
export TSSHBATCH=&quot;-n jluser -p l00n3y&quot;
726
 
</pre>
727
 
<p>This would cause all subsequent invocations of <tt class="docutils literal">tsshbatch</tt> to
728
 
attempt to use the login name/password credentials of <tt class="docutils literal">jluser</tt> and
729
 
<tt class="docutils literal">l00n3y</tt> respectively.</p>
730
 
<p><tt class="docutils literal">tsshbatch</tt> also supports searching for files over specified
731
 
paths with the <tt class="docutils literal">$TSSHBATCHCMDS</tt> and <tt class="docutils literal">$TSSHBATCHHOSTS</tt> environment
732
 
variables.  Their use is described later in this document.</p>
733
 
</div>
734
 
<div class="section" id="ssh-configuration-file-processing">
735
 
<h1><a class="toc-backref" href="#id6">SSH CONFIGURATION FILE PROCESSING</a></h1>
736
 
<p><tt class="docutils literal">tsshbatch</tt> has limited support for ssh configuration files.  Only the
737
 
<tt class="docutils literal">HostName</tt> and <tt class="docutils literal">IdentityFile</tt> directives are currently supported.</p>
738
 
<p>By default, <tt class="docutils literal">tsshbatch</tt> will look in <tt class="docutils literal"><span class="pre">~/.ssh/config</span></tt> for this
739
 
configuration file.  However, the location of the file can be
740
 
overriden with the <tt class="docutils literal"><span class="pre">-C</span></tt> option.</p>
741
 
</div>
742
 
<div class="section" id="managing-inventory-host-files">
743
 
<h1><a class="toc-backref" href="#id7">MANAGING INVENTORY: HOST FILES</a></h1>
744
 
<p>Although you can specify a list of target hosts with one or more <tt class="docutils literal"><span class="pre">-H</span>
745
 
&quot;host host host&quot;</tt> command line options, this gets cumbersome when you
746
 
have to manage a large inventory of machines.  This is what &quot;host files&quot;
747
 
are intended to do.</p>
748
 
<p>Host files are files that name a host, one per line.  They may
749
 
contain comments, include other host files, and make reference to
750
 
previously defined variables.  Here's an example, let's call it
751
 
<tt class="docutils literal"><span class="pre">stage-servers</span></tt>:</p>
752
 
<pre class="literal-block">
753
 
# Example staging host list
754
 

	
755
 
.define __EXTERNAL__ = splat.com
756
 

	
757
 
stage1.example.com
758
 
stage2.example.com
759
 
stage3.__EXTERNAL__
760
 
</pre>
761
 
<p>Say you'd like to get the uptime for each of these servers:</p>
762
 
<pre class="literal-block">
763
 
tsshbatch.py -x -i stage-servers uptime
764
 
</pre>
765
 
<p>You can have more than one of these on a command line:</p>
766
 
<pre class="literal-block">
767
 
tsshbatch.py -x -i dev-servers -i stage-servers -i prod-servers uptime
768
 
</pre>
769
 
<p>But ... that's kind of clumsy.  Instead let's create a new host file
770
 
called <tt class="docutils literal"><span class="pre">all-servers</span></tt> like this:</p>
771
 
<pre class="literal-block">
772
 
# Master host list
773
 

	
774
 
.include dev-servers
775
 
.include stage=servers
776
 
.include prod-servers
777
 
</pre>
778
 
<p>Now our command looks like this:</p>
779
 
<pre class="literal-block">
780
 
tsshbatch.py -x -i all-servers uptime
781
 
</pre>
782
 
<p>You can put as many <tt class="docutils literal"><span class="pre">-i</span></tt> arguments as you wish on the command line.
783
 
The contents of these files will be run in the order they appear from
784
 
left-to-right on the command line.</p>
785
 
<p>You can organize your host files in any hierarchy you like by making
786
 
use of search paths, as described later in this document.</p>
787
 
<p>The use of host files, the <tt class="docutils literal"><span class="pre">-H</span></tt> command line option, <tt class="docutils literal">.includes</tt>,
788
 
and variable substitution, give <tt class="docutils literal">tsshbatch</tt> a very powerful way to
789
 
manage complex host inventories.  There may be times when you'd like
790
 
to select a subset of that inventory but <em>run some other program with
791
 
those host names</em>.  This is most commonly the case when you'd like to
792
 
interactively <tt class="docutils literal">ssh</tt> into each host for some reason.</p>
793
 
<p>That's what the <tt class="docutils literal"><span class="pre">-W</span></tt> command line option is for.  <tt class="docutils literal">tsshbatch</tt> computes
794
 
the inventory you've specified, spits it out as single line of text and exits,
795
 
thereby enabling things like this:</p>
796
 
<pre class="literal-block">
797
 
for server in $(tsshbatch.py -i dev-servers -i dr-servers -W)
798
 
do
799
 
  ssh $server
800
 
done
801
 
</pre>
802
 
<p>This allows you to do all your intentory management via <tt class="docutils literal">tsshbatch</tt>
803
 
constructs, but make use of it with any other program of your
804
 
choosing.</p>
805
 
</div>
806
 
<div class="section" id="managing-jobs-command-files">
807
 
<h1><a class="toc-backref" href="#id8">MANAGING JOBS: COMMAND FILES</a></h1>
808
 
<p>Although <tt class="docutils literal">tsshbatch</tt> accepts command to be run on each host on its
809
 
own command line, this gets cumbersome for multi-step activities.  The
810
 
<tt class="docutils literal"><span class="pre">-f</span></tt> option allows you to specify one or more &quot;command files&quot; that
811
 
list the things you want done, in order.</p>
812
 
<p>Command files may include other command files, make use of variables,
813
 
and even specify sudo commands.  For example:</p>
814
 
<pre class="literal-block">
815
 
# This is a comment
816
 
.include master_commands  # optional, can be repeated
817
 
command1                  # a command to run on each host
818
 
sudo foo                  # run foo with sudo promotion on each host
819
 
</pre>
820
 
<p>Notice that this is not the same thing as a shell script.  There are
821
 
no conditionals or other programming features.  The contents of a
822
 
command file are more-or-less a &quot;to do&quot; list for each host.  If your
823
 
job requires the complexity of a &quot;real&quot; language, write script in
824
 
the language of your choice, and then make reference to that script
825
 
in a command file.</p>
826
 
<p>If you've specified a command file containing the commands you want run
827
 
via the <tt class="docutils literal"><span class="pre">-f</span></tt> option, these commands will run <em>before</em> the command
828
 
you've defined on the command line.  That one is always the last
829
 
command run on each host.</p>
830
 
<p>Command files may freely make use of comments and variable definitions
831
 
as described below.  They also have a special directive available,
832
 
<tt class="docutils literal">.notify</tt>.  This directive tells <tt class="docutils literal">tsshbatch</tt> to print descriptive
833
 
messages to <tt class="docutils literal">stdout</tt> as the commands in the file are executed on a
834
 
remote host.  This is helpful when running long, complex jobs:</p>
835
 
<pre class="literal-block">
836
 
# Example cmdfile
837
 

	
838
 
.include /my/fine/options
839
 
.define __JOB_NAME__
840
 
.notify starting JOB_NAME processing
841
 
/usr/local/__JOB_NAME__
842
 
.notify starting phase 2 of __JOB_NAME__
843
 
do_another_command
844
 
</pre>
845
 
<p>Notifications are entirely optional <em>and do not run on the remote
846
 
host</em>.  Think of them as runtime comments emitted by <tt class="docutils literal">tsshbatch</tt> to
847
 
help you know what's going on.  Notifications are supressed if you
848
 
select silent operation (<tt class="docutils literal"><span class="pre">-s</span></tt>).</p>
849
 
<p>You can also specify file transfers within a command file.  See the
850
 
section below on file transfers for all the details.</p>
851
 
<p>You can put as many <tt class="docutils literal"><span class="pre">-f</span></tt> arguments as you wish on the command line.
852
 
The contents of these files will be run in the order they appeare from
853
 
left-to-right on the command line.</p>
854
 
<p>You can organize your command files in any hierarchy you like by making
855
 
use of search paths, as described later in this document.</p>
856
 
</div>
857
 
<div class="section" id="searching-your-host-and-command-files">
858
 
<h1><a class="toc-backref" href="#id9">SEARCHING YOUR HOST AND COMMAND FILES</a></h1>
859
 
<p>Over time, you will probably build up a large set of host files for
860
 
describing your inventory and command files for standard jobs you
861
 
run often.  It's convenient to search through them quickly when
862
 
you're looking for something specific.</p>
863
 
<p>The <tt class="docutils literal"><span class="pre">-L</span></tt> command line option just lists every host file and command
864
 
file <tt class="docutils literal">tsshbatch</tt> knows about on all defined search paths.  This is
865
 
handy if you want to examine your hierarchy of files.</p>
866
 
<p>The <tt class="docutils literal"><span class="pre">-F</span> string string ...</tt> command line option looks through all
867
 
your host <em>and</em> command files and returns the names of those that
868
 
contain any of the strings you've listed.  The match is
869
 
case-insensitive and literal - no regular expressions are supported.</p>
870
 
<p>The <tt class="docutils literal"><span class="pre">-V</span> string string ...</tt> command line option is the inverse
871
 
of <tt class="docutils literal"><span class="pre">-F</span></tt>.  It returns a list of host and command files that do
872
 
<em>not contain</em> the strings you specify.  Again, the match is
873
 
literal and case-insensitive.</p>
874
 
</div>
875
 
<div class="section" id="features-and-use-cases">
876
 
<h1><a class="toc-backref" href="#id10">FEATURES AND USE CASES</a></h1>
877
 
<p>The sections below describe the various features of <tt class="docutils literal">tsshbatch</tt> in
878
 
more detail as well as common use scenarios.</p>
879
 
<div class="section" id="different-ways-to-specify-targeted-hostnames">
880
 
<h2><a class="toc-backref" href="#id11">Different Ways To Specify Targeted Hostnames</a></h2>
881
 
<p>There are two ways to specify the list of hosts on which you want
882
 
to run the specified command:</p>
883
 
<blockquote>
884
 
<ul>
885
 
<li><p class="first">On the command line via the <tt class="docutils literal"><span class="pre">-H</span></tt> option:</p>
886
 
<pre class="literal-block">
887
 
tsshbatch.py -H 'hostA hostB' uname -a
888
 
</pre>
889
 
<p>This would run the command <tt class="docutils literal">uname <span class="pre">-a</span></tt> on the
890
 
hosts <tt class="docutils literal">hostA</tt> and <tt class="docutils literal">hostB</tt> respectively.</p>
891
 
<p>Notice that the list of hosts must be separated by spaces but
892
 
passed as a <em>single argument</em>.  Hence we enclose them in single
893
 
quotes.</p>
894
 
</li>
895
 
<li><p class="first">Via a host list file:</p>
896
 
<pre class="literal-block">
897
 
tsshbatch.py myhosts df -Ph
898
 
</pre>
899
 
<p>Here, <tt class="docutils literal">tsshbatch</tt> expects the file <tt class="docutils literal">myhosts</tt> to contain a list
900
 
of hosts, one per line, on which to run the command <tt class="docutils literal">df <span class="pre">-Ph</span></tt>. As
901
 
an example, if you want to target the hosts <tt class="docutils literal">larry</tt>, <tt class="docutils literal">curly</tt>
902
 
and <tt class="docutils literal">moe</tt> in <tt class="docutils literal">foo.com</tt>, <tt class="docutils literal">myhosts</tt> would look like this:</p>
903
 
<pre class="literal-block">
904
 
larry.foo.com
905
 
curly.foo.com
906
 
moe.foo.com
907
 
</pre>
908
 
<p>This method is handy when there are standard &quot;sets&quot; of hosts on
909
 
which you regularly work.  For instance, you may wish to keep a
910
 
host file list for each of your production hosts, each of your
911
 
test hosts, each of your AIX hosts, and so on.</p>
912
 
<p>You may use the <tt class="docutils literal">#</tt> comment character freely throughout a host
913
 
list file to add comments or temporarily comment out a particular
914
 
host line.</p>
915
 
<p>You can even use the comment character to temporarily comment out
916
 
one or most hosts in the list given to the <tt class="docutils literal"><span class="pre">-H</span></tt> command line
917
 
argument.  For example:</p>
918
 
<pre class="literal-block">
919
 
tsshbatch.py -H &quot;foo #bar baz&quot; ls
920
 
</pre>
921
 
<p>This would run the <tt class="docutils literal">ls</tt> command on hosts <tt class="docutils literal">foo</tt> and <tt class="docutils literal">baz</tt> but
922
 
not <tt class="docutils literal">bar</tt>.  This is handy if you want to use your shell's
923
 
command line recall to save typing but only want to repeat the
924
 
command for some of the hosts your originally Specified.</p>
925
 
</li>
926
 
</ul>
927
 
</blockquote>
928
 
</div>
929
 
<div class="section" id="authentication-using-name-and-password">
930
 
<h2><a class="toc-backref" href="#id12">Authentication Using Name And Password</a></h2>
931
 
<p>The simplest way to use <tt class="docutils literal">tsshbatch</tt> is to just name the hosts
932
 
can command you want to run:</p>
933
 
<pre class="literal-block">
934
 
tsshbatch.py linux-prod-hosts uptime
935
 
</pre>
936
 
<p>By default, <tt class="docutils literal">tsshbatch</tt> uses your login name found in the <tt class="docutils literal">$USER</tt>
937
 
environment variable when logging into other systems.  In this
938
 
example, you'll be prompted only for your password which <tt class="docutils literal">tsshbatch</tt>
939
 
will then use to log into each of the machines named in
940
 
<tt class="docutils literal"><span class="pre">linux-prod-hosts</span></tt>.  (<em>Notice that his assumes your name and
941
 
password are the same on each host!</em>)</p>
942
 
<p>Typing in your login credentials all the time can get tedious after
943
 
awhile so <tt class="docutils literal">tsshbatch</tt> provides a means of providing them on the
944
 
command line:</p>
945
 
<pre class="literal-block">
946
 
tsshbatch.py -n joe.luser -p my_weak_pw linux-prod-hosts uptime
947
 
</pre>
948
 
<p>This allows you to use <tt class="docutils literal">tsshbatch</tt> inside scripts for hands-free
949
 
operation.</p>
950
 
<p>If your login name is the same on all hosts, you can simplify this
951
 
further by defining it in the environment variable:</p>
952
 
<pre class="literal-block">
953
 
export TSSHBATCH=&quot;-n joe.luser&quot;
954
 
</pre>
955
 
<p>Any subsequent invocation of <tt class="docutils literal">tsshbatch</tt> will only require a
956
 
password to run.</p>
957
 
<p>HOWEVER, there is a huge downside to this - your plain text password
958
 
is exposed in your scripts, on the command line, and possibly your
959
 
command history.  This is a pretty big security hole, especially if
960
 
you're an administrator with extensive privileges.  (This is why the
961
 
<tt class="docutils literal">ssh</tt> program does not support such an option.)  For this reason, it
962
 
is strongly recommended that you use the <tt class="docutils literal"><span class="pre">-p</span></tt> option sparingly, or
963
 
not at all.  A better way is to push ssh keys to every machine and use
964
 
key exchange authentication as described below.</p>
965
 
<p>However, there are times when you do have use an explicit password,
966
 
such as when doing <tt class="docutils literal">sudo</tt> invocations.  It would be really nice to
967
 
use <tt class="docutils literal"><span class="pre">-p</span></tt> and avoid having to constantly type in the password.  There
968
 
are two strategies for doing this more securely than just entering it
969
 
in plain text on the command line:</p>
970
 
<blockquote>
971
 
<ul>
972
 
<li><p class="first">Temporarily store it in the environment variable:</p>
973
 
<pre class="literal-block">
974
 
export TSSHBATCH=&quot;-n joe.luser -p my_weak_pw&quot;
975
 
</pre>
976
 
<p>Do this <em>interactively</em> after you log in, not from a script
977
 
(otherwise you'd just be storing the plain text password in a
978
 
different script).  The environment variable will persist as long
979
 
as you're logged in and disappear when you log out.</p>
980
 
<p>If you use this just make sure to observe three security
981
 
precautions:</p>
982
 
<blockquote>
983
 
<ol class="arabic">
984
 
<li><p class="first">Clear your screen immediately after doing this so no one
985
 
walking by can see the password you just entered.</p>
986
 
</li>
987
 
<li><p class="first">Configure your shell history system to ignore commands
988
 
beginning with <tt class="docutils literal">export TSSHBATCH</tt>.  That way your plain
989
 
text password will never appear in the shell command history.</p>
990
 
</li>
991
 
<li><p class="first">Make sure you don't leave a logged in session unlocked so
992
 
that other users could walk up and see your password by
993
 
displaying the environment.</p>
994
 
</li>
995
 
</ol>
996
 
</blockquote>
997
 
<p>This approach is best when you want your login credentials
998
 
available for the duration of an <em>entire login session</em>.</p>
999
 
</li>
1000
 
<li><p class="first">Store your password in an encrypted file and decrypt it inline.</p>
1001
 
<p>First, you have to store your password in an encrypted format.
1002
 
There are several ways to do this, but <tt class="docutils literal">gpg</tt> is commonly used:</p>
1003
 
<pre class="literal-block">
1004
 
echo &quot;my_weak_pw&quot; | gpg -c &gt;mysecretpw
1005
 
</pre>
1006
 
<p>Provide a decrypt passphrase, and you're done.</p>
1007
 
<p>Now, you can use this by decrypting it inline as needed:</p>
1008
 
<pre class="literal-block">
1009
 
#!/bin/sh
1010
 
# A demo scripted use of tsshbatch with CLI password passing
1011
 

	
1012
 
MYPW=`cat mysecretpw | gpg`   # User will be prompted for unlock passphrase
1013
 

	
1014
 
tsshbatch.py -n joe.luser -p $MYPW -i hostlist1 command1 arg
1015
 
tsshbatch.py -n joe.luser -p $MYPW -i hostlist2 command2 arg
1016
 
tsshbatch.py -n joe.luser -p $MYPW -i hostlist3 command3 arg
1017
 
</pre>
1018
 
<p>This approach is best when you want your login credentials
1019
 
available for the duration of <em>the execution of a script</em>.  It
1020
 
does require the user to type in a passphrase to unlock the
1021
 
encrypted password file, but your plain text password never
1022
 
appears in the wild.</p>
1023
 
</li>
1024
 
</ul>
1025
 
</blockquote>
1026
 
</div>
1027
 
<div class="section" id="authentication-using-key-exchange">
1028
 
<h2><a class="toc-backref" href="#id13">Authentication Using Key Exchange</a></h2>
1029
 
<p>For most applications of <tt class="docutils literal">tsshbatch</tt>, it is much simpler to use
1030
 
key-based authentication.  For this to work, you must first have
1031
 
pushed ssh keys to all your hosts.  You then instruct <tt class="docutils literal">tsshbatch</tt> to
1032
 
use key-based authentication rather than name and password.  Not only
1033
 
does this eliminate the need to constantly provide name and password,
1034
 
it also eliminates passing a plain text password on the command line
1035
 
and is thus far more secure.  This also overcomes the problem of
1036
 
having different name/password credentials on different hosts.</p>
1037
 
<p>By default, <tt class="docutils literal">tsshbatch</tt> will prompt for name and password if they
1038
 
are not provided on the command line.  To force key- authentication,
1039
 
use the <tt class="docutils literal"><span class="pre">-k</span></tt> option:</p>
1040
 
<pre class="literal-block">
1041
 
tsshbatch.py -k AIX-prod-hosts ls -al
1042
 
</pre>
1043
 
<p>This is so common that you may want to set it in your <tt class="docutils literal">$TSSHBATCH</tt>
1044
 
environment variable so that keys are used by default.  If you do
1045
 
this, there may still be times when you want for force prompting for
1046
 
passwords rather than using keys.  You can do this with the <tt class="docutils literal"><span class="pre">-K</span></tt>
1047
 
option which effectively overrides any prior <tt class="docutils literal"><span class="pre">-k</span></tt> selection.</p>
1048
 
</div>
1049
 
<div class="section" id="executing-a-sudo-command">
1050
 
<h2><a class="toc-backref" href="#id14">Executing A <tt class="docutils literal">sudo</tt> Command</a></h2>
1051
 
<p><tt class="docutils literal">tsshbatch</tt> is smart enough to handle commands that begin with the
1052
 
<tt class="docutils literal">sudo</tt> command.  It knows that such commands <em>require</em> a password no
1053
 
matter how you initially authenticate to get into the system.  If you
1054
 
provide a password - either via interactive entry or the <tt class="docutils literal"><span class="pre">-p</span></tt>
1055
 
option - by default, <tt class="docutils literal">tsshbatch</tt> will use that same password for
1056
 
<tt class="docutils literal">sudo</tt> promotion.</p>
1057
 
<p>If you provide no password - you're using <tt class="docutils literal"><span class="pre">-k</span></tt> and have not provided
1058
 
a password via <tt class="docutils literal"><span class="pre">-p</span></tt> - <tt class="docutils literal">tsshbatch</tt> will prompt you for the password
1059
 
<tt class="docutils literal">sudo</tt> should use.</p>
1060
 
<p>You can force <tt class="docutils literal">tsshbatch</tt> to ask you for a <tt class="docutils literal">sudo</tt> password with
1061
 
the <tt class="docutils literal"><span class="pre">-S</span></tt> option.  This allows you to have one password for initial
1062
 
login, and a different one for <tt class="docutils literal">sudo</tt> promotion.</p>
1063
 
<p>Any time you a prompted for a <tt class="docutils literal">sudo</tt> password and a login password
1064
 
has been provided (interactive or <tt class="docutils literal"><span class="pre">-p</span></tt>), you can accept this as the
1065
 
<tt class="docutils literal">sudo</tt> password by just hitting <tt class="docutils literal">Enter</tt>.</p>
1066
 
<div class="note">
1067
 
<p class="first admonition-title">Note</p>
1068
 
<p><tt class="docutils literal">tsshbatch</tt> makes a reasonable effort to scan your command
1069
 
line and/or command file contents to spot explicit
1070
 
invocations of the form <tt class="docutils literal">sudo ...</tt>.  It will ignore these
1071
 
if they are inside single- or double quoted strings, on the
1072
 
assumption that you're quoting the literal string <tt class="docutils literal">sudo
1073
 
...</tt> for some other purpose.</p>
1074
 
<p>However, this is not perfect because it is not a full
1075
 
reimplementation of the shell quoting and aliasing features.
1076
 
For example, if you invoke an alias on the remote machine
1077
 
that resolves to a <tt class="docutils literal">sudo</tt> command, or you run a script
1078
 
with a <tt class="docutils literal">sudo</tt> command in it, <tt class="docutils literal">tsshbatch</tt> has no way to
1079
 
determine what you're trying to do.  For complex
1080
 
applications, it's best to write a true shell script, push
1081
 
it all the machines in question via <tt class="docutils literal"><span class="pre">-P</span></tt>, and then have
1082
 
<tt class="docutils literal">tsshbatch</tt> remotely invoke it with <tt class="docutils literal">sudo myscript</tt> or
1083
 
something similar.</p>
1084
 
<p class="last">As always, the best way to figure out what the program
1085
 
thinks you're asking for is to run it in test mode and look
1086
 
at the diagnostic output.</p>
1087
 
</div>
1088
 
</div>
1089
 
<div class="section" id="precedence-of-authentication-options">
1090
 
<h2><a class="toc-backref" href="#id15">Precedence Of Authentication Options</a></h2>
1091
 
<p><tt class="docutils literal">tsshbatch</tt> supports these various authentication options in a
1092
 
particular heirarchy using a &quot;first match wins&quot; scheme.  From highest
1093
 
to lowest, the precedence is:</p>
1094
 
<blockquote>
1095
 
<ol class="arabic">
1096
 
<li><p class="first">Key exchange</p>
1097
 
</li>
1098
 
<li><p class="first">Forced prompting for name via -N. Notice this cancels any
1099
 
previously requested key exchange authentication.</p>
1100
 
</li>
1101
 
<li><p class="first">Command Line/$TSSHBATCH environment variable sets name</p>
1102
 
</li>
1103
 
<li><p class="first">Name picked up from $USER  (Default behavior)</p>
1104
 
</li>
1105
 
</ol>
1106
 
</blockquote>
1107
 
<p>If you try to use Key Exchange and <tt class="docutils literal">tsshbatch</tt> detects a command
1108
 
beginning with <tt class="docutils literal">sudo</tt>, it will prompt you for a password anyway.
1109
 
This is because <tt class="docutils literal">sudo</tt> requires a password to promote privilege.</p>
1110
 
</div>
1111
 
<div class="section" id="file-transfers">
1112
 
<h2><a class="toc-backref" href="#id16">File Transfers</a></h2>
1113
 
<p>The <tt class="docutils literal"><span class="pre">-G</span></tt> and <tt class="docutils literal"><span class="pre">-P</span></tt> options specify file <tt class="docutils literal">GET</tt> and <tt class="docutils literal">PUT</tt>
1114
 
respectively.  Both are followed by a quoted file transfer
1115
 
specification in the form:</p>
1116
 
<pre class="literal-block">
1117
 
&quot;path-to-source-file path-to-destination-directory&quot;
1118
 
</pre>
1119
 
<p>Note that this means the file will always be stored under its original
1120
 
name in the destination directory.  <em>Renaming isn't possible during
1121
 
file transfer</em>.</p>
1122
 
<p>However, <tt class="docutils literal">tsshbatch</tt> always does <tt class="docutils literal">GETs</tt> then <tt class="docutils literal">PUTs</tt> <em>then</em> any
1123
 
outstanding command (if any) at the end of the command line.  This
1124
 
permits things like renaming on the remote machine after a <tt class="docutils literal">PUT</tt>:</p>
1125
 
<pre class="literal-block">
1126
 
tsshbatch.py -P &quot;foo ./&quot; -i hostlist mv -v foo foo.has.a.new.name
1127
 
</pre>
1128
 
<p><tt class="docutils literal">GETs</tt> are a bit of a different story because you are retrieving a
1129
 
file of the same name on every host.  To avoid having all but the last
1130
 
one clobber the previous one, <tt class="docutils literal">tsshbatch</tt> makes forces the files you
1131
 
<tt class="docutils literal">GET</tt> to be uniquely named by prepending the hostname and a &quot;-&quot; to
1132
 
the actual file name:</p>
1133
 
<pre class="literal-block">
1134
 
tsshbatch.py -H myhost -G &quot;foo ./&quot;
1135
 
</pre>
1136
 
<p>This saves the file <tt class="docutils literal"><span class="pre">myhost-foo</span></tt> in the <tt class="docutils literal">./</tt> on your a local
1137
 
machine.</p>
1138
 
<p>These commands do not recognize any special directory shortcut symbols
1139
 
like <tt class="docutils literal">~/</tt> like the shell interpreter might.  You must name file and
1140
 
directory locations using ordinary pathing conventions.  You can put
1141
 
as many of these requests on the command line as you like to enable
1142
 
<tt class="docutils literal">GETs</tt> and <tt class="docutils literal">PUTs</tt> of multiple files.  You cannot, however, use
1143
 
filename wildcards to specify multi-file operations.</p>
1144
 
<p>You can put multiple <tt class="docutils literal">GETs</tt> or <tt class="docutils literal">PUTs</tt> on the command line for the
1145
 
same file.  They do not override each other but are <em>cummulative</em>. So
1146
 
this:</p>
1147
 
<pre class="literal-block">
1148
 
tsshbatch.py -P&quot;foo ./&quot; -P&quot;foo /tmp&quot; ...
1149
 
</pre>
1150
 
<p>Would put local file <tt class="docutils literal">foo</tt> in both <tt class="docutils literal">./</tt> and <tt class="docutils literal">/tmp</tt> on each host
1151
 
specified. Similarly, you can specify multiple files to <tt class="docutils literal">GET</tt> from
1152
 
remote hosts and place them in the same local directory:</p>
1153
 
<pre class="literal-block">
1154
 
tsshbatch.py -G&quot;/etc/fstab ./tmp&quot; -G&quot;/etc/rc.conf ./tmp&quot; ...
1155
 
</pre>
1156
 
<p>You may also put file transfer specifications into a command file via
1157
 
the <tt class="docutils literal">.getfile</tt> and <tt class="docutils literal">.putfile</tt> directives.  This is handy when you
1158
 
have many to do and don't want to clutter up the command line.  Each
1159
 
must be on its own line in the command file and in the same form as if
1160
 
it were provided on the command line:</p>
1161
 
<pre class="literal-block">
1162
 
.getfile /path/to/srcfile destdir    # This will get a file
1163
 
.putfile /path/to/srcfile destdir    # This will put a file
1164
 
</pre>
1165
 
<p>File transfers are done in the order they appear.  For instance, if
1166
 
you have a file transfer specification on the command line and then
1167
 
make reference to a command file with a file transfer specification in
1168
 
it, the one on the command line gets done first.</p>
1169
 
<div class="note">
1170
 
<p class="first admonition-title">Note</p>
1171
 
<p>Keep in mind that <tt class="docutils literal">tsshbatch</tt> always processes file
1172
 
transfers <em>before</em> executing any commands, no matter what
1173
 
order they appear in the command file.  If you have this in a
1174
 
command file:</p>
1175
 
<pre class="literal-block">
1176
 
echo &quot;Test&quot;
1177
 
.putfile &quot;./myfile /foo/bar/baz/&quot;
1178
 
</pre>
1179
 
<p class="last">The file will be transferred <em>before</em> the <tt class="docutils literal">echo</tt> command
1180
 
gets run.  This can be counterintuitive.  It's therefore
1181
 
recommended that you put your file transfers into a single
1182
 
file, and <tt class="docutils literal">.include</tt> it as the first thing in your
1183
 
command file to make it obvious that these will be run first.</p>
1184
 
</div>
1185
 
<p>By default, <tt class="docutils literal">tsshbatch</tt> aborts if any file transfer fails.  This is
1186
 
unlike the case of failed commands which are reported but do <em>not</em>
1187
 
abort the program.  The rationale' for this is that you may be doing
1188
 
both file transfer and command execution with a single <tt class="docutils literal">tsshbatch</tt>
1189
 
invocation, and the commands may depend on a file being transfered
1190
 
first.</p>
1191
 
<p>If you are sure no such problem exists, you can use the <tt class="docutils literal"><span class="pre">-a</span></tt> option
1192
 
to disable abort-after-failure semantics on file transfer.  In this
1193
 
case, file transfer errors will be reported, but <tt class="docutils literal">tsshbatch</tt> will
1194
 
continue on to the next transfer request.</p>
1195
 
<p><tt class="docutils literal">tsshbatch</tt> does preserve permissions when transferring files.
1196
 
Obviously, for this to work, the destination has to be writable by the
1197
 
ID you're logging in with.</p>
1198
 
<div class="note">
1199
 
<p class="first admonition-title">Note</p>
1200
 
<p class="last">The file transfer logic cannot cope with filenames that
1201
 
contain spaces.  The workaround is to either temporarily
1202
 
rename them, or put them in a container like a tarball or
1203
 
zip file and transfer that instead.</p>
1204
 
</div>
1205
 
</div>
1206
 
<div class="section" id="commenting">
1207
 
<h2><a class="toc-backref" href="#id17">Commenting</a></h2>
1208
 
<p>Both the command file and host file can be freely commented
1209
 
using the <tt class="docutils literal">#</tt> character.  Everything from that character to the end
1210
 
of that line is ignored.  Similarly, you can use whitespace freely,
1211
 
except in cases where it would change the syntax of a command or host
1212
 
name.</p>
1213
 
</div>
1214
 
<div class="section" id="includes">
1215
 
<h2><a class="toc-backref" href="#id18">Includes</a></h2>
1216
 
<p>You may also include other files as you wish with the <tt class="docutils literal">.include
1217
 
filename</tt> directive anywhere in the command file or host file.
1218
 
This is useful for breaking up long lists of things into smaller
1219
 
parts.  For example, suppose you have three host lists, one for each
1220
 
major production areas of your network:</p>
1221
 
<pre class="literal-block">
1222
 
hosts-development
1223
 
hosts-stage
1224
 
host-production
1225
 
</pre>
1226
 
<p>You might typically run different <tt class="docutils literal">tsshbatch</tt> jobs on each of these
1227
 
sets of hosts.  But suppose you now want to run a job on all of them.
1228
 
Instead of copying them all into a master file (which would be
1229
 
instantly obsolete if you changed anything in one of the above files),
1230
 
you could create <tt class="docutils literal"><span class="pre">hosts-all</span></tt> with this content:</p>
1231
 
<pre class="literal-block">
1232
 
.include hosts-development
1233
 
.include hosts-stage
1234
 
.include hosts-production
1235
 
</pre>
1236
 
<p>that way if you edited any of the underlying files, the
1237
 
<tt class="docutils literal"><span class="pre">hosts-all</span></tt> would reflect the change.</p>
1238
 
<p>Similarly you can do the same thing with the command file to group
1239
 
similar commands into separate files and include them.</p>
1240
 
<p><tt class="docutils literal">tsshbatch</tt> does not enforce a limit on how deeply nested
1241
 
<tt class="docutils literal">.includes</tt> can be.  An included file can include another file and
1242
 
so on.  However, if a circular include is detected, the program will
1243
 
notify you and abort.  This happens if, say, file1 includes file2,
1244
 
file2 includes file3, and file3 includes file1.  This would create an
1245
 
infinite loop of includes if permitted.  You can, of course, include
1246
 
the same file multiple times, either in a single file or throughout
1247
 
other included files, so long as no circular include is created.</p>
1248
 
<p>The target of a <tt class="docutils literal">.include</tt> directive can also contain variable
1249
 
references.  Note, however, that references to builtin variables will
1250
 
fail unless you have overriden them.  Why?  Because builtins don't get
1251
 
defined until a host connection is attempted.  This doesn't happen
1252
 
until <em>after</em> all global variable processing and file includes
1253
 
have been done.  So:</p>
1254
 
<pre class="literal-block">
1255
 
.define MYINCLUDE = /some/fine/file                    # OK
1256
 
.include MYINCLUDE
1257
 

	
1258
 
.define MYINCLUDE = ! find /some/path -name includeski # OK
1259
 
.include MYINCLUDE
1260
 

	
1261
 
.include __HOSTNAME__   # Nope, not defined yet -
1262
 
                        # tries to include file called '__HOSTNAME__'
1263
 

	
1264
 
.define __HOSTNAME__ ! hostname  # Override the builtin
1265
 
.include __HOSTNAME__                                   # OK
1266
 
</pre>
1267
 
<p>As a matter of keeping things simple, stick to global variables
1268
 
as part of an <tt class="docutils literal">.include</tt> target.</p>
1269
 
</div>
1270
 
<div class="section" id="search-paths">
1271
 
<h2><a class="toc-backref" href="#id19">Search Paths</a></h2>
1272
 
<p><tt class="docutils literal">tsshbatch</tt> supports the ablity to search paths to find files you've
1273
 
referenced.  The search path for <tt class="docutils literal">cmdfiles</tt> is specified in the
1274
 
<tt class="docutils literal">$TSSHBATCHCMDS</tt> environment variable.  The <tt class="docutils literal">hostlistfiles</tt> search
1275
 
path is specified in the <tt class="docutils literal">$TSSHBATCHHOSTS</tt> environment variable.
1276
 
These are both in standard path delimited format for your operating
1277
 
system.  For example, on Unix-like systems these look like this:</p>
1278
 
<pre class="literal-block">
1279
 
export TSSHBATCHCMDS=&quot;/usr/local/etc/.tsshbatch/commands:/home/me/.tsshbatch/commands&quot;
1280
 
</pre>
1281
 
<p>And so forth.</p>
1282
 
<p>These paths are honored both for any files you specify on the command
1283
 
line as well as for any files you reference in a <tt class="docutils literal">.include</tt>
1284
 
directive.  This allows you to maintain libraries of standard commands
1285
 
and host lists in well known locations and <tt class="docutils literal">.include</tt> the ones you
1286
 
need.</p>
1287
 
<p><tt class="docutils literal">tsshbatch</tt> will always first check to see if a file you've
1288
 
specified is in your local (invoking) directory and/or whether it is a
1289
 
fully qualified file name before attempting to look down a search
1290
 
path.  If a file exist in several locations, the first instance found
1291
 
&quot;wins&quot;.  So, for instance, if you have a file called <tt class="docutils literal">myhosts</tt>
1292
 
somewhere in the path defined in <tt class="docutils literal">$TSSHBATCHHOSTS</tt>, you can override
1293
 
it by creating a file of same name in your current working directory.</p>
1294
 
<p><tt class="docutils literal">tsshbatch</tt> also checks for so-called &quot;circular includes&quot; which
1295
 
would cause an infinite inclusion loop.  It will abort upon
1296
 
discovering this, prior to any file transfers or commands being
1297
 
executed.</p>
1298
 
</div>
1299
 
<div class="section" id="an-overview-of-variables">
1300
 
<h2><a class="toc-backref" href="#id20">An Overview Of Variables</a></h2>
1301
 
<p>As you become more sophisticated in your use of <tt class="docutils literal">tsshbatch</tt>, you'll
1302
 
begin to see the same patterns of use over and over again.  Variables
1303
 
are a way for you to use &quot;shortcuts&quot; to reference long strings
1304
 
without having to type the whole string in every time.  So, for example,
1305
 
instead of having to type in a command like this:</p>
1306
 
<pre class="literal-block">
1307
 
myfinecommand -X -Y -x because this is a really long string
1308
 
</pre>
1309
 
<p>You can just define variable like this:</p>
1310
 
<pre class="literal-block">
1311
 
.define __MYCMD__ =  myfinecommand -X -Y -x because this is a really long string
1312
 
</pre>
1313
 
<p>From then on, instead of typing in that long command on the command line or in
1314
 
a command file, you can just use <tt class="docutils literal">__MYCMD__</tt> and <tt class="docutils literal">tsshbatch</tt> will substitute
1315
 
the string as you defined it whenever it encounters the variable.</p>
1316
 
<p>Variables can be used pretty much everwhere:</p>
1317
 
<blockquote>
1318
 
<ul>
1319
 
<li><p class="first">In <tt class="docutils literal">hostlistfiles</tt> or in the hostnames listed with <tt class="docutils literal"><span class="pre">-H</span></tt>:</p>
1320
 
<pre class="literal-block">
1321
 
.define __MYDOMAIN__ = stage.mydomain.com
1322
 
#.define __MYDOMAIN__ = prod.mydomain.com
1323
 

	
1324
 
host1.__MYDOMAIN__
1325
 
host2.__MYDOMAIN__
1326
 
</pre>
1327
 
<p>Now you can switch <tt class="docutils literal">tsshbatch</tt> operation from stage to prod simply
1328
 
by changing what is commented out at the beginning.</p>
1329
 
</li>
1330
 
<li><p class="first">In file transfer specifications:</p>
1331
 
<pre class="literal-block">
1332
 
tsshbatch.py -xP&quot;./fstab-__MYHOSTNAME__  ./&quot; -i hostlist
1333
 
tsshbatch.py -xG&quot;/etc/__OSNAME__-release ./&quot; -i hostlist
1334
 
</pre>
1335
 
</li>
1336
 
<li><p class="first">In <tt class="docutils literal">cmdfiles</tt>:</p>
1337
 
<pre class="literal-block">
1338
 
.define __SHELL__ = /usr/local/bin/bash
1339
 

	
1340
 
__SHELL__ -c myfinescript
1341
 
</pre>
1342
 
</li>
1343
 
</ul>
1344
 
</blockquote>
1345
 
<div class="note">
1346
 
<p class="first admonition-title">Note</p>
1347
 
<p>A variable can have pretty much any name you like excepting
1348
 
the use of metacharacters like <tt class="docutils literal">&lt;</tt> or <tt class="docutils literal">!</tt>.  But if
1349
 
you are not careful, you can cause unintended errors:</p>
1350
 
<pre class="literal-block">
1351
 
.define foo = Slop
1352
 

	
1353
 
myfoodserver.foods.com
1354
 
</pre>
1355
 
<p>When you run <tt class="docutils literal">tsshbatch</tt> it will then turn the server name
1356
 
into <tt class="docutils literal">mySlopdserver.Slopds.com</tt> - probably not what you
1357
 
want.</p>
1358
 
<p class="last">So, it's a Really Good Idea (tm) to use some kind of naming
1359
 
scheme to make variables names stand out and make them
1360
 
unlikely to conflict accidentally with command- and host
1361
 
strings.</p>
1362
 
</div>
1363
 
</div>
1364
 
<div class="section" id="types-of-variables">
1365
 
<h2><a class="toc-backref" href="#id21">Types Of Variables</a></h2>
1366
 
<p><tt class="docutils literal">tsshbatch</tt> has four different kinds of variables:</p>
1367
 
<blockquote>
1368
 
<ul>
1369
 
<li><p class="first"><em>Global Variables</em> are the kind in the example above.
1370
 
You, the user, define them as you wish in a command file or
1371
 
host file.</p>
1372
 
</li>
1373
 
<li><p class="first"><em>Local Variables</em> work exactly the same a global variables, except
1374
 
that they can only be used in the file (command- or host) in which
1375
 
they are defined.  These variables are defined with the <tt class="docutils literal">.local
1376
 
name = value</tt> syntax.</p>
1377
 
</li>
1378
 
<li><p class="first"><em>Execution Variables</em> run any program or script of your choosing
1379
 
(on the same machine you're running <tt class="docutils literal">tsshbatch</tt>) and assign
1380
 
the results to either a global- or locala variable.</p>
1381
 
</li>
1382
 
<li><p class="first"><em>Builtin Variables</em> are variables the <tt class="docutils literal">tsshbatch</tt> itself
1383
 
defines.  You can override their default values by creating
1384
 
a Global Variable of the same name.</p>
1385
 
</li>
1386
 
</ul>
1387
 
</blockquote>
1388
 
</div>
1389
 
<div class="section" id="where-and-when-do-variables-get-processed">
1390
 
<h2><a class="toc-backref" href="#id22">Where And When Do Variables Get Processed?</a></h2>
1391
 
<p>Global, Local, and Execution Variables are defined in either a
1392
 
host file or command file.</p>
1393
 
<p>Builtin Variables are defined within <tt class="docutils literal">tsshbatch</tt> itself unless you
1394
 
override them.</p>
1395
 
<p>Global Variables are <em>all</em> read in and <em>then</em> used.  If you do
1396
 
something like this:</p>
1397
 
<pre class="literal-block">
1398
 
.define __FOO__ = firstfoo
1399
 
echo __FOO__
1400
 
.define __FOO__ = secondfoo
1401
 
</pre>
1402
 
<p>You'll get an output of ... <tt class="docutils literal">secondfoo</tt>!  Why?  Because before
1403
 
<tt class="docutils literal">tsshbatch</tt> tries to run anything, it has to process all the
1404
 
<tt class="docutils literal">cmdfiles</tt>, host file, and the command line content.  So,
1405
 
before we ever get around to doing an <tt class="docutils literal">echo __FOO__</tt> on some host,
1406
 
the second definition of __FOO__ has been read in ... and last
1407
 
definition wins.</p>
1408
 
<p>Local Variables are read in as a command- or host file is
1409
 
processed.  They can only be referenced <em>within the same
1410
 
file</em> - i.e., They are not visible to any other file.</p>
1411
 
<p>Execution Variables are processed a single time <em>at the time they're
1412
 
read in</em> from a command file or host file.</p>
1413
 
<p>Builtin Variables get evaluated <em>every time ``tsshbatch`` prepares to
1414
 
connect to a new host</em> (unless you've overriden them).  That way, the
1415
 
most current value for them is available for use on the next host.</p>
1416
 
<p>Keep in mind that <tt class="docutils literal">tsshbatch</tt> isn't a programming language.  It's
1417
 
&quot;variables&quot; are simple string substitutions with &quot;last one wins&quot;
1418
 
semantics (for globals).  If you define the same global variable in,
1419
 
say, a command file and also in the host file, the latter will &quot;win&quot;.
1420
 
Why?  Because <tt class="docutils literal">hostlistfiles</tt> are always read in after any
1421
 
<tt class="docutils literal">cmdfiles</tt>.</p>
1422
 
<p>Finally, variable references in a definition are <em>ignored</em>.  Say you
1423
 
do this in a command file:</p>
1424
 
<pre class="literal-block">
1425
 
.define __CLEVER      __ = __REALLYCLEVER__
1426
 
.define __REALLYCLEVER__ = Not That Smart
1427
 
echo __CLEVER__
1428
 
</pre>
1429
 
<p>You will get this output, <tt class="docutils literal">__REALLYCLEVER__</tt>!  Why?  Because, the
1430
 
variable references on the right side of a definition statement are
1431
 
never replaced.  This is a concious design choice to keep variable
1432
 
definition and use as simple and obvious as possible.  Allowing such
1433
 
&quot;indirect&quot; definitions opens up a treasure trove of maintenance pain
1434
 
you really want to avoid.  Trust us on this one.</p>
1435
 
</div>
1436
 
<div class="section" id="global-variables">
1437
 
<h2><a class="toc-backref" href="#id23">Global Variables</a></h2>
1438
 
<p><tt class="docutils literal">tsshbatch</tt> allows you to define variables which will then be used
1439
 
to replace matching strings in <tt class="docutils literal">cmdfiles</tt>, <tt class="docutils literal">hostlistfiles</tt>, and
1440
 
file transfer specifications.  For example, suppose you have this in a
1441
 
host file:</p>
1442
 
<pre class="literal-block">
1443
 
.define DOMAIN=.my.own.domain.com
1444
 

	
1445
 
host1DOMAIN
1446
 
host2DOMAIN
1447
 
host3DOMAIN
1448
 
</pre>
1449
 
<p>At runtime, the program will actually connect to
1450
 
<tt class="docutils literal">host1.my.own.domain.com</tt>, <tt class="docutils literal">host2.my.domain.com</tt>, and so on.  This
1451
 
allows for ease of modularization and maintenance of your files.</p>
1452
 
<p>Similarly, you might want define <tt class="docutils literal">MYCMD=some_long_string</tt> so you
1453
 
don't have to type <tt class="docutils literal">some_long_string</tt> over and over again in a
1454
 
command file.</p>
1455
 
<p>There are some &quot;gotchas&quot; to this:</p>
1456
 
<blockquote>
1457
 
<ul>
1458
 
<li><p class="first">The general form of a variable definition is:</p>
1459
 
<pre class="literal-block">
1460
 
.define name = value
1461
 
</pre>
1462
 
<p>You have to have a name but the value is optional.  <tt class="docutils literal">.define
1463
 
FOO=</tt> simply replaces any subsequent <tt class="docutils literal">FOO</tt> strings with
1464
 
nothing, effectively removing them.</p>
1465
 
<p>Any <tt class="docutils literal">=</tt> symbols to the right of the one right after <tt class="docutils literal">name</tt> are
1466
 
just considered part of the variable's value.</p>
1467
 
<p>Whitespace around the <tt class="docutils literal">=</tt> symbol is optional but allowed.</p>
1468
 
</li>
1469
 
<li><p class="first">Variables are substituted in the order they appear:</p>
1470
 
<pre class="literal-block">
1471
 
.define LS = ls -alr
1472
 
LS /etc               # ls -alr /etc
1473
 
.define LS = ls -1
1474
 
LS /foo               # ls -1 /foo
1475
 
</pre>
1476
 
</li>
1477
 
<li><p class="first">Variable names and values are <em>case sensitive</em>.</p>
1478
 
</li>
1479
 
<li><p class="first">Variables may be defined in either <tt class="docutils literal">cmdfiles</tt> or
1480
 
<tt class="docutils literal">hostlistfiles</tt> but they are <em>visible to any subsequent file
1481
 
that gets read</em>.  For instance, <tt class="docutils literal">cmdfiles</tt> are read before any
1482
 
<tt class="docutils literal">hostlistfiles</tt>.  Any variables you've defined in a command file
1483
 
that happen to match a string in one of your hostnames will be
1484
 
substituted.</p>
1485
 
<p>This is usually not what you want, so be careful.  One way to
1486
 
manage this is to use variables names that are highly unlikely to
1487
 
ever show up in a hostname or command.  That way your commands and
1488
 
hostnames will not accidentally get substrings replaced with
1489
 
variable values.  For example, you might use variable names like
1490
 
<tt class="docutils literal"><span class="pre">--MYLSCOMMAND--</span></tt> or <tt class="docutils literal">__DISPLAY_VGS__</tt>.</p>
1491
 
</li>
1492
 
<li><p class="first">Variable substitution is also performed on any host names
1493
 
or commands passed on the command line.</p>
1494
 
</li>
1495
 
</ul>
1496
 
</blockquote>
1497
 
</div>
1498
 
<div class="section" id="local-variables">
1499
 
<h2><a class="toc-backref" href="#id24">Local Variables</a></h2>
1500
 
<p>As we saw previously, global variables have &quot;last one wins&quot;
1501
 
semantics.  So, if the same variable name appears in different
1502
 
files, the last instance read will be the value assigned to
1503
 
that variable.  Sometimes, you don't want this behavior. You
1504
 
want to define a variable in a file and <em>only use it there
1505
 
without changing a global variable with the same name</em>.</p>
1506
 
<p>Say we have three files:</p>
1507
 
<pre class="literal-block">
1508
 
# First command file
1509
 
.define __DEFAULT__ = ls -al  # global variable
1510
 

	
1511
 
# Second command file
1512
 
.local __DEFAULT__ = ls -1    # variable is local to 2nd file
1513
 
__DEFAULT__
1514
 

	
1515
 

	
1516
 
# Third command file
1517
 
__DEFAULT__
1518
 
</pre>
1519
 
<p>Now, say we run this command:</p>
1520
 
<pre class="literal-block">
1521
 
tsshbatch.py -xH&quot;somehost&quot; -f file1 -f file2 -f file3
1522
 
</pre>
1523
 
<p>The net commands to be run on <tt class="docutils literal">somehost</tt> will be:</p>
1524
 
<pre class="literal-block">
1525
 
ls -1
1526
 
ls -al
1527
 
</pre>
1528
 
<p>The reference to <tt class="docutils literal">__DEFAULT</tt> in <tt class="docutils literal">file2</tt> is resolved with the
1529
 
<em>local</em> definition, and the reference in <tt class="docutils literal">file3</tt> is resolved with
1530
 
the <em>global</em> definition.</p>
1531
 
<p>Local variables accompish several things.  First, they &quot;insulate&quot; a
1532
 
host- or command file from prior- or subsequent variable definitions
1533
 
found in other files.  You are guaranteed that the local copy of a
1534
 
varaible always &quot;wins&quot;.</p>
1535
 
<p>Conversely, local variables also protect global variables of the same
1536
 
name from changing.  In the example above, we have default behavior
1537
 
which can be overriden in a case-by-case basis, without changing the
1538
 
&quot;master&quot; definition.</p>
1539
 
</div>
1540
 
<div class="section" id="execution-variables">
1541
 
<h2><a class="toc-backref" href="#id25">Execution Variables</a></h2>
1542
 
<p>Execution Variables are actually a special case of Global and Local
1543
 
Variables.  That is, they are evaluated at the same time and in the
1544
 
same manner as any other variable.  The difference is that a normal
1545
 
variable describes a <em>literal string replacement</em>.  But an Execution
1546
 
Variable <em>runs a command, program, or script and assigns the results
1547
 
to the variable</em>.</p>
1548
 
<p>For example, suppose you want create a file on many machines, and you
1549
 
want that file to be named based on who ran the <tt class="docutils literal">tsshbatch</tt> job.
1550
 
You might do this in a command file:</p>
1551
 
<pre class="literal-block">
1552
 
.define __WHOAMI__ = ! whoami
1553
 
touch __WHOAMI__-Put_This_Here.txt
1554
 
</pre>
1555
 
<p>So, if ID <tt class="docutils literal">luser</tt> is running <tt class="docutils literal">tsshbatch</tt>, a file called
1556
 
<tt class="docutils literal"><span class="pre">luser-Put_This_Here.txt</span></tt> will be created (or have its timestamp
1557
 
updated) on every machine in the host file or named with
1558
 
<tt class="docutils literal"><span class="pre">-H</span></tt>.</p>
1559
 
<p>Similarly, you can do the same thing with local variables:</p>
1560
 
<pre class="literal-block">
1561
 
.local __TYPE__ = ! uname
1562
 
</pre>
1563
 
<p>Notice it is the <tt class="docutils literal">!</tt> character that distinguishes an Execution
1564
 
Variable from a Global Variable.  It is this character that
1565
 
tells <tt class="docutils literal">tsshbatch</tt>, &quot;Go run the command to the right of me and return
1566
 
the results.&quot;  The trailing space is optional and the definition could
1567
 
be written as:</p>
1568
 
<pre class="literal-block">
1569
 
.define __WHOAMI__ = !whoami
1570
 
</pre>
1571
 
<p>If the command you specify returns multiple lines of output, it's up
1572
 
to you to process it properly.  <tt class="docutils literal">tsshbatch</tt> does no newline
1573
 
stripping or other postprocessing of the command results.  This can
1574
 
make the output really &quot;noisy&quot;.  <tt class="docutils literal">tssbatch</tt> normally reports
1575
 
a summary of the command and its results.  But if you do something
1576
 
like this:</p>
1577
 
<pre class="literal-block">
1578
 
.define __LS__ = ! ls -al
1579
 
echo __LS__
1580
 
</pre>
1581
 
<p>You will get a multiline summary of the command and then the actual
1582
 
output - which is also multiline.  This gets to be obnonxious pretty
1583
 
quickly.  You can make a lot of this go away with the <tt class="docutils literal"><span class="pre">-q</span></tt>, or
1584
 
&quot;quiet&quot; option.</p>
1585
 
<div class="note">
1586
 
<p class="first admonition-title">Note</p>
1587
 
<p class="last">It's important to remember that the program you are invoking
1588
 
<em>runs on the same machine as</em> <tt class="docutils literal">tsshbatch</tt> <em>itself</em>, NOT each
1589
 
host you are sending commands to.  In other words, just
1590
 
like Builtin Variables, Execution Variables are <em>locally
1591
 
defined</em>.</p>
1592
 
</div>
1593
 
</div>
1594
 
<div class="section" id="builtin-variables">
1595
 
<h2><a class="toc-backref" href="#id26">Builtin Variables</a></h2>
1596
 
<p>As noted previously, Builtin Variables are created by <tt class="docutils literal">tsshbatch</tt>
1597
 
itself.  They are created for each new host connection so that things
1598
 
like time, host number, and hostname are up-to-date.</p>
1599
 
<p>As of this release, <tt class="docutils literal">tsshbatch</tt> supports the following Builtins:</p>
1600
 
<blockquote>
1601
 
<table border="1" class="docutils">
1602
 
<colgroup>
1603
 
<col width="22%" />
1604
 
<col width="78%" />
1605
 
</colgroup>
1606
 
<tbody valign="top">
1607
 
<tr><td><tt class="docutils literal">__DATE__</tt></td>
1608
 
<td>Date in YYYYMMDD format</td>
1609
 
</tr>
1610
 
<tr><td><tt class="docutils literal">__DATETIME__</tt></td>
1611
 
<td>Date and time in YYYYMMDDHHMMSS format</td>
1612
 
</tr>
1613
 
<tr><td><tt class="docutils literal">__HOSTNAME__</tt></td>
1614
 
<td>Full name of current host as passed to <tt class="docutils literal">tsshbatch</tt></td>
1615
 
</tr>
1616
 
<tr><td><tt class="docutils literal">__HOSTNUM__</tt></td>
1617
 
<td>Count of host being processed, starting at 1</td>
1618
 
</tr>
1619
 
<tr><td><tt class="docutils literal">__HOSTSHORT__</tt></td>
1620
 
<td>Leftmost component of hostname as passed to <tt class="docutils literal">tsshbatch</tt></td>
1621
 
</tr>
1622
 
<tr><td><tt class="docutils literal">__LOGINNAME__</tt></td>
1623
 
<td>User name used for remote login.  For key auth, name of tsshbatch user.</td>
1624
 
</tr>
1625
 
<tr><td><tt class="docutils literal">__TIME__</tt></td>
1626
 
<td>Time in HHMMSS format</td>
1627
 
</tr>
1628
 
</tbody>
1629
 
</table>
1630
 
</blockquote>
1631
 
</div>
1632
 
<div class="section" id="using-builtin-variables">
1633
 
<h2><a class="toc-backref" href="#id27">Using Builtin Variables</a></h2>
1634
 
<p>There are times when it's convenient to be able to embed the name of
1635
 
the current host in either a command or in a file transfer
1636
 
specification.  For example, suppose you want to use a single
1637
 
invocation of <tt class="docutils literal">tsshbatch</tt> to transfer files in a host-specific way.
1638
 
You might name your files like this:</p>
1639
 
<pre class="literal-block">
1640
 
myfile.host1
1641
 
myfile.host2
1642
 
</pre>
1643
 
<p>Now, all you have to do is this:</p>
1644
 
<pre class="literal-block">
1645
 
tsshbatch.py -xH &quot;host 1 host2&quot; -P &quot;myfile.__HOSTNAME__ ./&quot;
1646
 
</pre>
1647
 
<p>When run, <tt class="docutils literal">tsshbatch</tt> will substitute the name of the current host
1648
 
in place of the string <tt class="docutils literal">__HOSTNAME__</tt>.  (<em>Note that these are
1649
 
**double*</em> underbars on each side of the string.*)</p>
1650
 
<p>You can do this in commands (and commands within command files) as
1651
 
well:</p>
1652
 
<pre class="literal-block">
1653
 
tsshbatch.py -x hosts 'echo I am running on __HOSTNAME__'
1654
 
</pre>
1655
 
<p>Be careful to escape and quote things properly, especially from the
1656
 
the command line, since <tt class="docutils literal">&lt;</tt> and <tt class="docutils literal">&gt;</tt> are recognized by the shell as
1657
 
metacharacters.</p>
1658
 
<p>There are two forms of host name substitution possible.  The first,
1659
 
<tt class="docutils literal">__HOSTNAME__</tt> will use the name <em>as you provided it</em>, either as an
1660
 
argument to <tt class="docutils literal"><span class="pre">-H</span></tt> or from within a host file.</p>
1661
 
<p>The second, <tt class="docutils literal">__HOSTSHORT__</tt>, will only use the portion of the name
1662
 
string you provided up to the leftmost period.</p>
1663
 
<p>So, if you specify <tt class="docutils literal">myhost1.frumious.edu</tt>, <tt class="docutils literal">__HOSTNAME__</tt> will be
1664
 
replaced with that entire string, and <tt class="docutils literal">__HOSTSHORT__</tt> will be
1665
 
replaced by just <tt class="docutils literal">myhost1</tt>.</p>
1666
 
<p>Notice that, in no case does <tt class="docutils literal">tsshbatch</tt> do any DNS lookups to
1667
 
figure this stuff out.  It just manipulates the strings you provide as
1668
 
hostnames.</p>
1669
 
<p>The symbols <tt class="docutils literal">__HOSTNAME__</tt> and <tt class="docutils literal">__HOSTSHORT__</tt> are like any other
1670
 
symbol you might have specified yourself with <tt class="docutils literal">.define</tt>.  <em>This
1671
 
means you can override their meaning</em>.  For instance, say you're doing
1672
 
this:</p>
1673
 
<pre class="literal-block">
1674
 
tsshbatch.py -x myhosts  echo &quot;It is: __HOSTNAME__&quot;
1675
 
</pre>
1676
 
<p>As you would expect, the program will log into that host, echo the
1677
 
hostname and exit.  But suppose you don't want it to echo something
1678
 
else for whatever reason.  You'd create a command file with this
1679
 
entry:</p>
1680
 
<pre class="literal-block">
1681
 
.define __HOSTNAME__ = Really A Different Name
1682
 
</pre>
1683
 
<p>Now, when you run the command above, the output is:</p>
1684
 
<pre class="literal-block">
1685
 
It is: Really A Different Name
1686
 
</pre>
1687
 
<p>In other words, <tt class="docutils literal">.define</tt> has a <em>higher precedence</em> than the
1688
 
preconfigured values of <tt class="docutils literal">HOSTNAME</tt> and <tt class="docutils literal">HOSTSHORT</tt>.</p>
1689
 
</div>
1690
 
<div class="section" id="noise-levels">
1691
 
<h2><a class="toc-backref" href="#id28">Noise Levels</a></h2>
1692
 
<p><tt class="docutils literal">tsshbatch</tt> defaults to a medium level of reporting as it runs.
1693
 
This includes connection reporting, headers describing the command
1694
 
being run on every host,and the results written to <tt class="docutils literal">stdin</tt> and
1695
 
<tt class="docutils literal">stdout</tt>.  Each line of reporting output begins with <tt class="docutils literal"><span class="pre">---&gt;</span></tt> to
1696
 
help you parse through the output if you happen to be writing a
1697
 
program that post-processes the results from <tt class="docutils literal">tsshbatch</tt>.</p>
1698
 
<p>This output &quot;noise&quot; is judged to be right for most applications of the
1699
 
program.  There are times, however, when you want more- or less
1700
 
&quot;noise&quot; in the output.  There are several <tt class="docutils literal">tsshbatch</tt> options that
1701
 
support this.</p>
1702
 
<p>These options <em>only affect reporting of
1703
 
commands you're running</em>.  They do not change the output of file
1704
 
transfer operations.  They also do not change error reporting, which
1705
 
is always the same irrespective of current noise level setting.</p>
1706
 
<p><tt class="docutils literal"><span class="pre">-q</span></tt> or &quot;quiet&quot; mode, reduces the amount of output noise in
1707
 
two ways.  First, it silences reporting each time a successful
1708
 
connection is made to a host.  Secondly, the command being run
1709
 
isn't reported in the header.   For example, normally, running
1710
 
<tt class="docutils literal">ls <span class="pre">-l</span></tt> is reported like this:</p>
1711
 
<pre class="literal-block">
1712
 
---&gt;  myhost:    SUCCESS: Connection Established
1713
 
---&gt;  myhost (stdout) [ls -l]:
1714
 
...
1715
 
---&gt;  myhost (stderr) [ls -l]:
1716
 
</pre>
1717
 
<p>In quiet mode, reporting looks like this:</p>
1718
 
<pre class="literal-block">
1719
 
---&gt;  localhost (stdout):
1720
 
...
1721
 
---&gt;  localhost (stderr):
1722
 
</pre>
1723
 
<p>The main reason for this is that some commands can be very long.
1724
 
With execution variables, it's possible to create commands that
1725
 
span many lines.  The quiet option gives you the ability to
1726
 
suppress echoing these long commands for each and every host
1727
 
in your list.</p>
1728
 
<p><tt class="docutils literal"><span class="pre">-y</span></tt> or &quot;noisy&quot; mode, produces normal output noise but
1729
 
also replicates the hostname and command string <em>for
1730
 
every line of output produced</em>.  For instance, <tt class="docutils literal">ls <span class="pre">-1</span></tt>
1731
 
might normally produce this:</p>
1732
 
<pre class="literal-block">
1733
 
---&gt;  myhost:    SUCCESS: Connection Established
1734
 
---&gt;  myhost (stdout) [ls -1]:
1735
 

	
1736
 
       backups
1737
 
       bin
1738
 
</pre>
1739
 
<p>But in noisy mode, you see this:</p>
1740
 
<pre class="literal-block">
1741
 
---&gt;  myhost:    SUCCESS: Connection Established                                                                                                                     ---&gt;  myhost (stdout) [ls -1]:
1742
 
[myhost (stdout) [ls -1]]        backups
1743
 
[myhost (stdout) [ls -1]]        bin
1744
 
</pre>
1745
 
<p>Again, the purpose here is to support post-processing where you might
1746
 
want to search through a large amount of output looking only for
1747
 
results from particular hosts or commands.</p>
1748
 
<p><tt class="docutils literal"><span class="pre">-s</span></tt> or &quot;silent&quot; mode returns <em>only the results from running the
1749
 
commands</em>.  No headers or descriptive information are produced.  It's
1750
 
more-or-less what you'd see if you logged into the host and ran the
1751
 
command interactively.  For instance, <tt class="docutils literal">ls <span class="pre">-l</span></tt> might look like this:</p>
1752
 
<pre class="literal-block">
1753
 
total 44
1754
 
drwxr-xr-x  2 splot splot 4096 Nov  5 14:54 Desktop
1755
 
drwxrwxr-x 39 splot splot 4096 Sep  9 14:57 Dev
1756
 
drwxr-xr-x  3 splot splot 4096 Jun 14  2012 Documents
1757
 
</pre>
1758
 
<p>The idea here is to use silent mode with the various variables
1759
 
described previously to customize your own reporting output.  Imagine
1760
 
you have this in a command file and you run <tt class="docutils literal">tsshbatch</tt> in silent
1761
 
mode:</p>
1762
 
<pre class="literal-block">
1763
 
.define __USER__ = ! echo $USER
1764
 
echo &quot;Run on __HOSTNAME__ on __DATE__ at __TIME__ by __USER__&quot;
1765
 
uname -a
1766
 
</pre>
1767
 
<p>You'd see output along these lines:</p>
1768
 
<pre class="literal-block">
1769
 
Run on myhost on 20991208 at 141659 by splot
1770
 
Linux myhost 3.11.0-12-generic #19-Ubuntu SMP Wed Oct 9 16:20:46 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux
1771
 
</pre>
1772
 
</div>
1773
 
</div>
1774
 
<div class="section" id="other">
1775
 
<h1><a class="toc-backref" href="#id29">OTHER</a></h1>
1776
 
<ul>
1777
 
<li><p class="first">Comments can go anywhere.</p>
1778
 
</li>
1779
 
<li><p class="first">Directives like <tt class="docutils literal">.define</tt> and <tt class="docutils literal">.include</tt> must be the first
1780
 
non-whitespace text on the left end of a line.  If you do this in a
1781
 
command file:</p>
1782
 
<pre class="literal-block">
1783
 
foo .include bar
1784
 
</pre>
1785
 
<p><tt class="docutils literal">tsshbatch</tt> thinks you want to run the command <tt class="docutils literal">foo</tt> with an
1786
 
argument of <tt class="docutils literal">.include bar</tt>.  If you do it in a host file,
1787
 
the program thinks you're trying to contact a host called <tt class="docutils literal">foo
1788
 
.include bar</tt>.  In neither case is this likely to be quite what you
1789
 
had in mind.  Similarly, everything to the right of the directive is
1790
 
considered its argument (up to any comment character).</p>
1791
 
</li>
1792
 
<li><p class="first">Whitespace is not significant at the beginning or end of a line but
1793
 
it is preserved within <tt class="docutils literal">.define</tt> and <tt class="docutils literal">.include</tt> directive
1794
 
arguments as well as within commmand definitions.</p>
1795
 
</li>
1796
 
<li><p class="first">Strictly speaking, you do not have to have whitespace after a
1797
 
directive.  This is recognized:</p>
1798
 
<pre class="literal-block">
1799
 
.includesomefileofmine
1800
 
.definemyvar=foo
1801
 
</pre>
1802
 
<p>But this is <em>strongly</em> discouraged because it's really hard to read.</p>
1803
 
</li>
1804
 
<li><p class="first"><tt class="docutils literal">tsshbatch</tt> writes the <tt class="docutils literal">stdout</tt> of the remote host(s) to
1805
 
<tt class="docutils literal">stdout</tt> on the local machine.  It similarly writes remote
1806
 
<tt class="docutils literal">stderr</tt> output to the local machine's <tt class="docutils literal">stderr</tt>.  If you wish to
1807
 
suppress <tt class="docutils literal">stderr</tt> output, either redirect it on your local command
1808
 
line or use the <tt class="docutils literal"><span class="pre">-e</span></tt> option to turn it off entirely.  If you want
1809
 
everything to go to your local <tt class="docutils literal">stdout</tt>, use the <tt class="docutils literal"><span class="pre">-E</span></tt> option.</p>
1810
 
</li>
1811
 
<li><p class="first">You must have a reasonably current version of Python 2.x installed.
1812
 
It almost certainly will not work on Python 3.x because it uses the
1813
 
deprecated <tt class="docutils literal">commands</tt> module.  This decision was made to make the
1814
 
program as backward compatible with older versions of Python as
1815
 
possible (there is way more 2.x around than there is 3.x).</p>
1816
 
</li>
1817
 
<li><p class="first">If your Python installation does not install <tt class="docutils literal">paramiko</tt> you'll
1818
 
have to install it manually, since <tt class="docutils literal">tsshbatch</tt> requires these
1819
 
libraries as well.</p>
1820
 
</li>
1821
 
<li><p class="first"><tt class="docutils literal">tsshbatch</tt> has been run extensively from Unix-like systems (Linux,
1822
 
FreeBSD) and has had no testing whatsoever on Microsoft Windows.  If
1823
 
you have experience using it on Windows, do please share with the
1824
 
class using the email address below.  While we do not officially
1825
 
support this tool on Windows, if the changes needed to make it work
1826
 
properly are small enough, we'd consider updating the code
1827
 
accordingly.</p>
1828
 
</li>
1829
 
</ul>
1830
 
</div>
1831
 
<div class="section" id="bugs-and-misfeatures">
1832
 
<h1><a class="toc-backref" href="#id30">BUGS AND MISFEATURES</a></h1>
1833
 
<ul>
1834
 
<li><p class="first">You will not be able to run remote <tt class="docutils literal">sudo</tt> commands if the host in
1835
 
question enables the <tt class="docutils literal">Defaults requiretty</tt> in its <tt class="docutils literal">sudoers</tt>
1836
 
configuration.  Some overzealous InfoSec folks seem to think this is
1837
 
a brilliant way to secure your system (they're wrong) and there's
1838
 
nothing <tt class="docutils literal">tsshbatch</tt> can do about it.</p>
1839
 
</li>
1840
 
<li><p class="first">When <tt class="docutils literal">sudo</tt> is presented a bad password, it ordinarily prints a
1841
 
string indicating something is wrong.  <tt class="docutils literal">tsshbatch</tt> looks for this
1842
 
to let you know that you've got a problem and then terminates
1843
 
further operation.  This is so that you do not attempt to log in
1844
 
with a bad password across all the hosts you have targeted.  (Many
1845
 
enterprises have policies to lock out a user ID after some small
1846
 
number of failed login/access attempts.)</p>
1847
 
<p>However, some older versions of <tt class="docutils literal">sudo</tt> (noted on a RHEL 4 host
1848
 
running <tt class="docutils literal">sudo</tt> 1.6.7p5) do not return any feedback when presented
1849
 
with a bad password.  This means that <tt class="docutils literal">tsshbatch</tt> cannot tell the
1850
 
difference between a successful <tt class="docutils literal">sudo</tt> and a system waiting for
1851
 
you to reenter a proper password.  In this situation, if you enter a
1852
 
bad password, the <em>the program will hang</em>.  Why?  <tt class="docutils literal">tsshbatch</tt>
1853
 
thinks nothing is wrong and waits for the <tt class="docutils literal">sudo</tt> command to
1854
 
complete.  At the same time, <tt class="docutils literal">sudo</tt> itself is waiting for an
1855
 
updated password.  In this case, you have to kill <tt class="docutils literal">tsshbatch</tt> and
1856
 
start over.  This typically requires you to put the program in
1857
 
background (<tt class="docutils literal"><span class="pre">`Ctrl-Z</span></tt> in most shells) and then killing that job
1858
 
from the command line.</p>
1859
 
<p>There is no known workaround for this problem.</p>
1860
 
</li>
1861
 
</ul>
1862
 
</div>
1863
 
<div class="section" id="other-similar-products">
1864
 
<h1><a class="toc-backref" href="#id31">OTHER, SIMILAR PRODUCTS</a></h1>
1865
 
<p>It's always interesting to see how other people approach the same
1866
 
problem.  If you're interested in this general area of IT automation,
1867
 
you may want to also look at <tt class="docutils literal">Ansible</tt>, <tt class="docutils literal">Capistrano</tt>, <tt class="docutils literal">Cluster
1868
 
SSH</tt>, <tt class="docutils literal">Fabric</tt>, <tt class="docutils literal">Func</tt>, and <tt class="docutils literal">Rundeck</tt>.</p>
1869
 
</div>
1870
 
<div class="section" id="copyright-and-licensing">
1871
 
<h1><a class="toc-backref" href="#id32">COPYRIGHT AND LICENSING</a></h1>
1872
 
<p><strong>tsshbatch</strong> is Copyright (c) 2011-2016 TundraWare Inc.</p>
1873
 
<p>For terms of use, see the <tt class="docutils literal"><span class="pre">tsshbatch-license.txt</span></tt> file in the
1874
 
program distribution.  If you install <strong>tsshbatch</strong> on a FreeBSD
1875
 
system using the 'ports' mechanism, you will also find this file in
1876
 
<tt class="docutils literal">/usr/local/share/doc/tsshbatch</tt>.</p>
1877
 
</div>
1878
 
<div class="section" id="author">
1879
 
<h1><a class="toc-backref" href="#id33">AUTHOR</a></h1>
1880
 
<pre class="literal-block">
1881
 
Tim Daneliuk
1882
 
tsshbatch&#64;tundraware.com
1883
 
</pre>
1884
 
</div>
1885
 
<div class="section" id="document-revision-information">
1886
 
<h1><a class="toc-backref" href="#id34">DOCUMENT REVISION INFORMATION</a></h1>
1887
 
<pre class="literal-block">
1888
 
$Id: '0c4840a tundra Sat Oct 15 15:29:02 2016 -0500'
1889
 
</pre>
1890
 
<p>This document was produced with <tt class="docutils literal">emacs</tt>, <tt class="docutils literal">RestructuredText</tt>, and <tt class="docutils literal">TeX Live</tt>.</p>
1891
 
<p>You can find the latest version of this program at:</p>
1892
 
<blockquote>
1893
 
<a class="reference external" href="http://www.tundraware.com/Software/tsshbatch">http://www.tundraware.com/Software/tsshbatch</a></blockquote>
1894
 
</div>
1895
 
</div>
1896
 
</body>
1897
 
</html>
0 comments (0 inline, 0 general)