1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340
|
.ig >>
<STYLE TYPE="text/css">
<!--
A:link{text-decoration:none}
A:visited{text-decoration:none}
A:active{text-decoration:none}
OL,UL,P,BODY,TD,TR,TH,FORM { font-family: arial,helvetica,sans-serif;; font-size:small; color: #333333; }
H1 { font-size: x-large; font-family: arial,helvetica,sans-serif; }
H2 { font-size: large; font-family: arial,helvetica,sans-serif; }
H3 { font-size: medium; font-family: arial,helvetica,sans-serif; }
H4 { font-size: small; font-family: arial,helvetica,sans-serif; }
-->
</STYLE>
<title>ploticus: shell command interface</title>
<body bgcolor=D0D0EE vlink=0000FF>
<br>
<br>
<center>
<table cellpadding=2 bgcolor=FFFFFF width=550><tr>
<td>
<table cellpadding=2 width=550><tr>
<td><br><h2>shell command interface</h2></td>
<td align=right>
<small>
<a href="../doc/welcome.html"><img src="../doc/ploticus.gif" border=0></a><br>
Version 2.33 Jun'06
</small><br><a href="../doc/scripthome.html">Scripts</a>
<td></tr></table>
</td></tr>
<td>
<br>
<br>
.>>
.TH shell_command_interface PL "02-JUN-2006 PL ploticus.sourceforge.net"
.SH Shell command interface
The \fB#shell\fR directive
provides a convenient facility for invoking shell commands and
capturing/parsing the results, for maximum flexibility in interfacing
with the shell and other programs.
Several
.ig >>
<a href="#examples">
.>>
\0examples
.ig >>
</a>
.>>
are provided below.
.LP
\fBSecurity concern:\fR
Before using #shell/#endshell in a network programming environment, developers must understand the potential for
security breaches, and realize that best practice is to avoid using untrusted-user-supplied values when building shell
commands. But since quisp does allow execution of shell commands, as a safety precaution it
performs automatic removal of hazardous shell metacharacters present in
variables that are evaluated within the \fC#shell / #endshell\fR construct.
The following are automatically removed when QUISP variables
are evaluated within a #shell / #endshell construct: \fC " ' ` $ \\ ; | ../ \fR
(this was updated with
.ig >>
<a href="../../download">
.>>
\0patch 1.27-01
.ig >>
</a>
.>>
).
The set of filtered metacharacters is configurable via
.ig >>
<a href="config.html">
.>>
\0config file
.ig >>
</a>
.>>
or
.ig >>
<a href="mode.html">
.>>
\0#mode command.
.ig >>
</a>
.>>
Developers that choose to use this feature are responsible for ensuring that the
metacharacter screening feature is operating as expected.
Enclosing all shell command line arguments in quotes may provide an extra measure of protection.
.LP
QUISP's internal mechanism for invoking shell commands uses \fCpopen(3C)\fR.
.ig >>
<br><br><br>
.>>
.SH #shell - #endshell
Issue a shell command.
The shell command can be one or more lines in length.
QUISP variables and other directives such as \fC#if\fR can be used to build the shell command,
(but \fC#sql\fR directives cannot be intermingled).
Results can be displayed directly or captured for further processing.
The shell command's exit code is available via
.ig >>
<a href="#functions">
.>>
\0$shellexitcode()
.ig >>
</a>
.>>
and the number of output lines is available via
.ig >>
<a href="#functions">
.>>
\0$shellrowcount().
.ig >>
</a>
.>>
.LP
Usage:
.nf
\0 #shell [\fImode\fC]
\0 \fIshellcommand(s)\fR
\0 ...
\0 #endshell\fR
.fi
.LP
\fBmode\fR may be one of the following. If not specified, #dump will be the default.
.IP
\fB#dump\fR - execute the shell command and write the results directly to standard output. This is the default.
.IP
\fB#processrows\fR - execute the shell command. The application must then fetch individual result lines using the \fC$shellrow()\fR
function (see below).
.IP
\fB#dumptab\fR - execute the shell command, parse result lines into fields, and write fields to standard output delimited by tabs.
.IP
\fB#dumphtml\fR - execute the shell command, parse result lines into fields, and write to standard output as HTML table rows.
.IP
\fB#dumpsilent\fR - execute the shell command, but don't display result lines at all. However a row count can be gotten by calling
the \fC$shellrowcount\fR function (see below).
.LP
.ig >>
<br><br><br>
.>>
.ig >>
<a name=functions></a>
.>>
.SH Functions
These functions may be used in conjunction with the \fC#shell\fR command:
.ig >>
<br><br>
.>>
.LP
\fB$shellrow( fieldname1, .., fieldnameN )\fR
.IP \0
Get the next line of shell command results and parse into fields.
Result fields are loaded into variables that use names \fIfieldname1 .. fieldnameN\fR.
Returns 0 on success, 1 if no more result lines, or an error code > 1.
When there are no more result lines, the result variables are all set to "".
(But if the shell command produces no results, the result variables are not set at all.)
.IP \0
If only one fieldname is given, the entire result line will be loaded.
If two or more fieldnames are given, result fields will be delimited on whitespace by default,
or TAB if \fC$shellfielddelim( tab )\fR was called previously, and individual fields will be
loaded into variables.
If \fC$shellreadheader()\fR was called initially to read a result field name header then
no fieldnames should be given with \fC$shellrow()\fR.
.IP \0
You can also use this function to capture \fCtag: value\fR result lines; to do this, use
\fC$shellrow( #varvaluepair )\fR, and values will be loaded into variables named using the tag.
.ig >>
<br><br><br>
.>>
.LP
\fB$shellrowcount( )\fR
.IP \0
Return the number of result rows produced by the most recently invoked shell command.
.ig >>
<br><br><br>
.>>
.LP
\fB$shellexitcode( )\fR
.IP \0
Return the final exit code of the most recently invoked shell command.
.ig >>
<br><br><br>
.>>
.LP
\fB$shellfielddelim( s )\fR
.IP \0
Set the delimitation method for parsing shell command result fields.
Allowable values for \fIs\fR
are \fCtab\fR, \fCwhitespace\fR, or \fCline\fR (which takes the entire
line, without trailing newline, as a field).
.IP \0
Example: \fC#call shellfielddelim( whitespace )\fR
.ig >>
<br><br><br>
.>>
.LP
\fB$shellfieldconvert( convertmode )\fR
.IP
Perform conversions on shell command result fields.
Currently the only supported \fCconvertmode\fR is \fCshsql\fR,
which causes conversions useful when using shell commands to process
shsql data files (nulls are converted to zero-length strings, and
embedded underscores are converted to spaces).
.IP \0
Example: \fC#call $shellfieldconvert( shsql )\fR
.ig >>
<br><br><br>
.>>
.LP
\fB$shellreadheader( delimtype )\fR
.IP \0
For shell commands that produce output where the first line contains field names,
this function can be used to load the header. Afterwards, \fC$shellrow()\fR,
if it is passed no arguments, will load fields into variables based on the header.
The \fIdelimtype\fR argument indicates delimitation of field name header and data;
it may be given as \fCtab\fR or \fCwhitespace\fR; if omitted, \fCwhitespace\fR is assumed.
.IP \0
Example:
.nf
\0 #shell
\0 mycommand
\0 #endshell
\0 #call $shellreadheader()
\0 #while $shellrow() = 0
\0 ...
.fi
.ig >>
<br><br><br>
.>>
.ig >>
<a name=examples></a>
.>>
.SH Examples
.LP
\fBExample 1. Get a numeric value out of the last line of a file and multiply it by 1.25:\fR
.nf
\0 #shell #processrows
\0 tail -1 today.dat | cut -f 3
\0 #endshell
\0 #call $shellrow(TODAY_TOTAL)
\0 #set MAX = $arith(@TODAY_TOTAL*1.25)
.fi
\fBExample 2. Invoke a grep command and display the results:\fR
.nf
\0 #set searchword = "macula"
\0 <pre>
\0 #shell
\0 grep "@searchword" /home/steve/textfiles/*
\0 #endshell
\0 </pre>
\0 #if $shellrowcount() != 0
\0 <h3>Nothing found</h3>
\0 #endif
.fi
.LP
\fBExample 3. Same as above but add a sed command and display results as HTML table rows:\fR
.nf
\0 #set searchword = "macula"
\0 <table cellpadding=2>
\0 #shell #dumphtml
\0 grep "@searchword" /home/steve/textfiles/* |
\0 sed "s/^.*://"
\0 #endshell
\0 </table>
\0 #if $shellrowcount() != 0
\0 <h3>Nothing found</h3>
\0 #endif
.fi
.LP
\fBExample 4. Invoke a command that computes correlations and process the results one row at a time:\fR
.nf
\0 #shell #processrows
\0 correlate all
\0 #endshell
\0 <table cellpadding=2>
\0 #while $shellrow( var1, var2, pearson, n ) == 0
\0 <tr><td>@var1</td><td>@var2</td><td>@pearson</td><td>N = @n</td></tr>
\0 #endloop
\0 </table>
\0 #if $shellrowcount() < 1
\0 <h3>No correlations computed</h3>
\0 #endif
.fi
.LP
\fBExample 5. Invoke a shell command and capture its exit code:\fR
.nf
\0 #shell
\0 addlog @DATE @TIME @READING
\0 #endshell
\0 #if $shellexitcode() != 0
\0 <h3>Addlog failed!</h3>
\0 #endif
.fi
.ig >>
<br>
<br>
</td></tr>
<td align=right>
<a href="../doc/welcome.html">
<img src="../doc/ploticus.gif" border=0></a><br><small>data display engine <br>
<a href="../doc/Copyright.html">Copyright Steve Grubb</a>
<br>
<br>
<center>
<img src="../gallery/all.gif">
</center>
</td></tr>
</table>
<br>
<center>
Ploticus is hosted at http://ploticus.sourceforge.net <br>
<img src="http://sourceforge.net/sflogo.php?group_id=38453" width="88" height="31" border="0" alt="SourceForge Logo">
</center>
.>>
|