75 ■ ■ ■ CHAPTER 11 MathfromtheShell M athematical calculations are an important element of writing shell scripts. In the various flavors of UNIX, there are multiple ways to perform just about any task, and math- ematical tasks are no exception. Although there are many types of mathematical computations, I’ve limited the discus- sion in this chapter to the basic operations of addition, subtraction, multiplication, and division, plus remainder, exponentiation, and trigonometric functions. The examples make use of the variables a, b, c, and d. One note on division: some programming languages don’t perform integer division like you might expect from using your traditional calculator. There are two parts to the quotient of an integer-division problem, the whole (or integer) part and the remainder. Take the example of 5 divided by 3; the whole part of the quotient is 1 and the remainder upon division is 2. In some of this chapter’s methods for doing math in the shell, there are two distinct operators for integer division. The slash (/) operator returns the whole part and the percent (%) operator returns the remainder. Keep this in mind when performing your calculations. expr This chapter’s first math method is the use of expr. expr is a utility that evaluates various types of expressions, including ones containing string, logical, and mathe- matical functions. The following are examples of how to use expr to carry out mathematical operations: Addition: answer=`expr $c + $d` Subtraction: answer=`expr $c - $d` Multiplication: answer=`expr $c \* $d` Division: answer=`expr $c / $d` Remainder: answer=`expr $c % $d` There are no explicit trigonometric or exponentiation functions in expr. 76 CHAPTER 11 ■ MATHFROMTHESHELL There are a couple of items to keep in mind when using expr. As shown in the exam- ples, single spaces are required between the expr call and its arguments, and between the operators and their arguments. Also, when using the asterisk (*) character for multiplica- tion, theshell will interpret it as a wild card and expand it to the elements in your current directory before attempting to evaluate the expression unless you either escape the aster- isk via \* or turn off globbing 1 (path and file expansion) using set -f. Internal ShellMathTheshell itself can perform mathematical operations. The advantage of using the internal math functions is that your code doesn’t have to call an external program, which reduces the footprint of the code and allows it to run faster. This method is available in bash and ksh. The Bourne shell does not have this functionality. The following are examples of how to employ internal shellmath to carry out mathematical operations. ■ Note The largest integer available for internal shellmath is 2 63 –1, or 9,223,372,036,854,775,807 (in bash and expr; ksh uses scientific notation for large numbers). This is the maximum 64-bit integer. If you need numbers that are larger than this, you must use the bc or dc calculator. Addition: answer=$(($c+$d)) Subtraction: answer=$(($c-$d)) Multiplication: answer=$(($c*$d)) Division: answer=$(($c/$d)) Remainder: answer=$(($c%$d)) Exponentiation: The first argument raised to the power of the second; answer=$(($c**$d)) Order of operations: The default order can be modified by using parentheses, as with the other methods of performing shell math; answer=$((($c+$d)*$c)). Without the use of parentheses to order the calculations as you desire, the common order is as follows: 1. Perform any calculations surrounded by parentheses. These are ones that you may not have specified. 1. Globbing is the term used for the shell’s completion of paths and filenames that contain metacharacters. CHAPTER 11 ■ MATHFROMTHESHELL 77 2. Perform all calculations that are exponents or roots, such as a square or cube root. 3. Working from left to right, perform any multiplication or division. 4. Working from left to right, perform any addition or subtraction. A math library available in ksh lets us perform more-sophisticated mathematical calcu- lations. These are the functions it provides: abs(), acos(), asin(), atan(), atan2(), cos(), cosh(), exp(), floor(), fmod(), hypot(), int(), log(), pow(), sin(), sinh(), sqrt(), tan(), and tanh(). Table 11-1 gives a basic description of these functions, but their use is beyond the scope of this book. The following variable assignment demonstrates the use of one of these higher level mathematical functions: answer=$((cos($a))) Table 11-1. Descriptions of Trigonometric Functions Available in ksh Trigonometric Function Description abs() Absolute value acos() Inverse cosine asin() Inverse sine atan() Inverse tangent atan2() Four-quadrant inverse tangent cos() Cosine cosh() Hyperbolic cosine exp() Exponential floor() Round toward negative infinity fmod() Floating-point remainder of division hypot() Square-root of sum of squares int() Integer portion of a real number log() Natural logarithm pow() Raise base number to an exponential power sin() Sine sinh() Hyperbolic sine sqrt() Square root tan() Tangent tanh() Hyperbolic tangent 78 CHAPTER 11 ■ MATHFROMTHESHELL bc The bc utility is an arbitrary-precision calculator. This means the precision of the answer can be set at runtime through the use of the scale operator. Most of the mathematical shell utilities described up to this point focus on operations on whole numbers. The exception is the special library of functions available in ksh. With bc, you can set the scale (number of decimal places following the decimal point) so that results will be expressed as floating- point numbers of the precision you specify. The functional use of bc is very similar to the use of expr, as the following list shows: Addition: answer=`echo "$c+$d" | bc` Subtraction: answer=`echo "$c-$d" | bc` Multiplication: answer=`echo "$c*$d" | bc` Division: answer=`echo "$c/$d" | bc` Remainder: answer=`echo "$c%$d" | bc` Exponentiation: answer=`echo "$c^$d" | bc` Scale: The scale of a floating-point number is the number of digits that follow the decimal point. To set the scale when performing a calculation, you use answer=`echo "scale=5;$c/$d" | bc`. Trigonometric functions: To use the trigonometric functions, you must enable themath library by invoking bc using the -l switch. When the library is enabled, the default scale is set to 20 decimal places. The following examples set the scale to 5 places: • Sine in radians: answer=`echo "scale=5;s($a)" | bc -l` • Cosine in radians: answer=`echo "scale=5;c($a)" | bc -l` • Arctangent in radians: answer=`echo "scale=5;s($a)" | bc -l` dc The dc utility is another arbitrary-precision calculator, and it works much like bc. Its main distinction lies in its use of reverse Polish notation. 2 dc uses a stack to store numbers; eval- uating a number pushes it onto the stack, and the operations pop their arguments off the stack and push the result back onto the stack. For shell scripting purposes, I have not used 2. More information on reverse Polish notation (RPN) can be found at http://en.wikipedia.org/wiki/ Reverse_polish_notation. CHAPTER 11 ■ MATHFROMTHESHELL 79 the dc calculator. It is a valuable program, but the majority of the calculations I’ve needed are fairly simple and don’t require the advantages it provides. I mention it only for the sake of completeness. . CHAPTER 11 Math from the Shell M athematical calculations are an important element of writing shell scripts. In the various flavors of UNIX, there are multiple. either escape the aster- isk via * or turn off globbing 1 (path and file expansion) using set -f. Internal Shell Math The shell itself can perform mathematical