mirror of
https://github.com/lcn2/calc.git
synced 2025-08-19 01:13:27 +03:00
302 lines
9.0 KiB
Plaintext
302 lines
9.0 KiB
Plaintext
Calc shell scripts
|
|
------------------
|
|
|
|
There are several ways calc may be used in shell scripts. The
|
|
syntax for these varies widely for different shells and systems,
|
|
but common to most are commands like echo, if, for, goto, shift,
|
|
and exit, as well as the accessing of environment parameters, shell
|
|
variables, and command-line arguments.
|
|
|
|
As a simple example, assuming a C or Bourne shell, let add be a
|
|
file containing just one line:
|
|
|
|
calc -q -- $1 + $2
|
|
|
|
Then:
|
|
|
|
./add 1.23 4.56
|
|
|
|
should respond with the display of:
|
|
|
|
5.9
|
|
|
|
The "-q" was included in the command to avoid reading of any
|
|
start-up calc files which could contain commands not wanted
|
|
here. The "--" indicates that there are no more options;
|
|
without it, if $1 began with '-', calc would interpret it as
|
|
the first character of another option. To execute the file,
|
|
the strings "1.23" and "4.56" were assigned to $1 and $2, so
|
|
calc was in effect asked to evaluate the string "1.23 + 4.56".
|
|
|
|
By making add executable by a command like:
|
|
|
|
chmod u+x add
|
|
|
|
the command used here may be simplified to:
|
|
|
|
./add 1.23 4.56
|
|
|
|
Here we shall assume that any script we refer to has been made
|
|
executable in this way.
|
|
|
|
Because $1 and $2, and instructions in the script, are to read
|
|
by calc as expressions or commands, they may be much more
|
|
complicated than in the above example, but if they involve
|
|
characters with special interpretations by the shell (spaces
|
|
for word separation, * or ? or [ ...] for file-name expansion,
|
|
! (without immediately following space) for history expansion,
|
|
( ... ) for shell-function arguments, { ... } for brace
|
|
expansion, $ for parameter or variable expansion, <, <<, >, >>
|
|
for redirection of input or output, etc.) it will usually be
|
|
necessary to quote or escape tho characters, or usually more
|
|
conveniently, quote whole expressions with single or double
|
|
quotes.
|
|
|
|
For example, the add script should have no problem with
|
|
commands like:
|
|
|
|
./add "sqrt(2)" "3 * 4"
|
|
|
|
./add "mat A[2,2] = {1,2,3,4}" "A^2"
|
|
|
|
./add "2 + 3i" "(3 + 4i)^2"
|
|
|
|
If the shell arguments are to be integers, one could use
|
|
scripts like the following with arithmetic expansion
|
|
for the bash and ksh:
|
|
|
|
declare -i a=$1
|
|
declare -i b=$2
|
|
calc -q -- $a + $b
|
|
|
|
and for csh:
|
|
|
|
@ a = $1
|
|
@ b = $2
|
|
calc -q -- $a + $b
|
|
|
|
Specifying the shell for a script may be done by including
|
|
in the script a first line with the "magic number" "#!" and
|
|
the full file path for the shell as in:
|
|
|
|
#!/bin/bash
|
|
declare -i a=$1
|
|
declare -i b=$2
|
|
calc -q -- $a + $b
|
|
|
|
For a script to multiply rather than add two expressions, one
|
|
could have a file mul with the one line:
|
|
|
|
calc -q -- $1 \* $2
|
|
or:
|
|
calc -q -- "$1 * $2"
|
|
|
|
which will work so long as $1 and $2 are literal numbers, but
|
|
will not work for:
|
|
|
|
./mul 2+3 4
|
|
or:
|
|
./mul "2 + 3" 4
|
|
|
|
both of which calc interprets as evaluating 2 + 3 * 4. What should
|
|
work for most shells is:
|
|
|
|
calc -q -- "($1) * ($2)"
|
|
|
|
For adding an arbitrary number of expressions that evaluate to
|
|
rational numbers expressible with at most 20 decimal places,
|
|
simple shell script could be used:
|
|
|
|
s=0
|
|
for i do
|
|
s=`calc -q -- $s + $i`
|
|
done
|
|
echo sum = $s
|
|
|
|
This is not particularly efficient since it calls calc once for
|
|
each argument. Also, a more serious script would permit more
|
|
general numbers.
|
|
|
|
Another way of handling a sum of several expressions is with
|
|
the script addall2 with a here document:
|
|
|
|
calc "-q -s" $* << +
|
|
global i, n, s;
|
|
n = argv();
|
|
for (i = 0; i < n; i++)
|
|
s += eval(argv(i));
|
|
print "sum =", s;
|
|
+
|
|
|
|
In executing the command:
|
|
|
|
./addall2 2 3 4
|
|
|
|
the $* in ths script expands to 2 3 4, and because of the "-s"
|
|
in the options, calc starts with argv(0) = "2", argv(1) = "3",
|
|
argv(2)= "4". As there is only one calc process involved and
|
|
the eval() function accepts as argument any string that
|
|
represents the body of a calc function, the strings argv(0),
|
|
argv(1), ... could evaluate to any value types for which the
|
|
additions to be performed are defined, and variables defined in
|
|
one argv() can be used in later arguments.
|
|
|
|
For systems that support interpreter files, essentially the
|
|
same thing may be done more efficiently by using calc as an
|
|
interpreter. Assuming the full path for calc is
|
|
/usr/local/bin/calc, one could use the file addall3 with contents
|
|
|
|
#!/usr/bin/calc -q -s -f
|
|
global i, n, s;
|
|
n = argv();
|
|
for (i = 1; i <= n; i++)
|
|
s += eval(argv(i));
|
|
print "sum =", s;
|
|
|
|
IMPORTANT NOTE:
|
|
|
|
The -f flag must be at the very end of the #! line.
|
|
The #! line must be the first line of the exeuctable file.
|
|
The path after the #! must be the full path to the calc executable.
|
|
|
|
After the command:
|
|
|
|
addall3 2 3 4
|
|
|
|
the arguments calc receives are argv(0) = "addall3", argv(1) =
|
|
"2", argv(3) = "3", argv(4) = "4".
|
|
|
|
Another kind of script that can be useful is sqrts1:
|
|
|
|
calc -q 'global s; while (scanf("%s", s) == 1) print sqrt(eval(s));'
|
|
|
|
or what is essentially an interpreter equivalent sqrts2:
|
|
|
|
#!/usr/local/bin/calc -q -f
|
|
global s;
|
|
while (scanf('%s', s) == 1)
|
|
print sqrt(eval(s));
|
|
|
|
If sqrts is either of these scripts, the command:
|
|
|
|
echo 27 2+3i | sqrts
|
|
|
|
or, if datafile contains the one line:
|
|
|
|
27 2+3i
|
|
|
|
or the two lines:
|
|
|
|
27
|
|
2+3i
|
|
|
|
either:
|
|
|
|
cat datafile | ./sqrts
|
|
or:
|
|
./sqrts < datafile
|
|
|
|
should display the square-roots of 27 and 2+3i. The output could
|
|
be piped to another command by | or directed to a file by use of
|
|
> or >>.
|
|
|
|
With no specified input, either sqrts1 or sqrts2 will wait
|
|
without any prompt for input from the keyboard and as each line
|
|
is completed display the square-roots of the expressions
|
|
entered. Exit can be achieved by entering exit or entering
|
|
ctrl-D (interpreted as EOF) rather than a line of input.
|
|
|
|
One advantage of an interpreter file like sqrts2 (which has only
|
|
options, but neither "-s" nor "--" in its first line) is that it
|
|
can be invoked with further options as in
|
|
|
|
echo 2 3 4 | ./sqrts2 -i -D 32
|
|
|
|
An advantage of non-interpreter files is that they can use shell
|
|
features. For example, for unquoted arguments or arguments in
|
|
double quotes parameter expansion (indicated by unquoted '$') and
|
|
command substitution (using backquotes) occur before lines are
|
|
compiled by calc. For example, if doit is an executable
|
|
script with contents
|
|
|
|
calc -q -- "$1($2)"
|
|
|
|
it may be used as in:
|
|
|
|
./doit sqrt 7
|
|
and:
|
|
./doit exp 7
|
|
|
|
to display the values of sqrt(7) and exp(7). The "--" prevents a
|
|
leading '-' in the $1 argument as indicating one or more additional
|
|
options. E.g., without the "--" in doit,
|
|
|
|
./doit -sqrt 7
|
|
|
|
would be interpreted as:
|
|
|
|
calc -q "-sqrt(7)"
|
|
|
|
in which the dash in the quoted part would be taken as indicating a
|
|
list of options -s, -q, -r, etc.; this would give an "illegal option"
|
|
error as calc has no -r option.
|
|
|
|
In invoking the doit script it is not necessary that $1 expand to a
|
|
calc function name and $2 to an expression; all that is required is
|
|
that:
|
|
|
|
$1($2)
|
|
|
|
expands to a string that calc will recognize as a command. E.g.:
|
|
|
|
./doit "define f(x) = x^2; 2 + mod" "f(7), 6"
|
|
|
|
does the same as:
|
|
|
|
calc -q -- "define f(x) = x^2; 2 + mod(f(7), 6)"
|
|
|
|
Essentially the same is achieved by the contents of doit is changed to:
|
|
|
|
calc -q -p -- << +
|
|
$1($2)
|
|
+
|
|
|
|
The "-p" stops calc going interactive; without it the effect would be
|
|
be the same as that of a script with the one line:
|
|
|
|
calc -q -i -- "$1($2)"
|
|
|
|
For more information use the following calc commands:
|
|
|
|
help usage
|
|
help argv
|
|
help config
|
|
help cscript
|
|
|
|
## Copyright (C) 2000 Landon Curt Noll and Ernest Bowen
|
|
##
|
|
## Calc is open software; you can redistribute it and/or modify it under
|
|
## the terms of the version 2.1 of the GNU Lesser General Public License
|
|
## as published by the Free Software Foundation.
|
|
##
|
|
## Calc is distributed in the hope that it will be useful, but WITHOUT
|
|
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
## or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
|
|
## Public License for more details.
|
|
##
|
|
## A copy of version 2.1 of the GNU Lesser General Public License is
|
|
## distributed with calc under the filename COPYING-LGPL. You should have
|
|
## received a copy with calc; if not, write to Free Software Foundation, Inc.
|
|
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
|
##
|
|
## @(#) $Revision: 29.7 $
|
|
## @(#) $Id: script,v 29.7 2004/10/23 00:41:11 chongo Exp $
|
|
## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/script,v $
|
|
##
|
|
## Under source code control: 1999/11/30 05:29:48
|
|
## File existed as early as: 1999
|
|
##
|
|
## chongo <was here> /\oo/\ http://www.isthe.com/chongo/
|
|
## Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
|
|
|