1.\" $NetBSD: expr.1,v 1.29 2008/04/30 13:10:46 martin Exp $ 2.\" 3.\" Copyright (c) 2000,2003 The NetBSD Foundation, Inc. 4.\" All rights reserved. 5.\" 6.\" This code is derived from software contributed to The NetBSD Foundation 7.\" by J.T. Conklin <jtc@NetBSD.org> and Jaromir Dolecek <jdolecek@NetBSD.org>. 8.\" 9.\" Redistribution and use in source and binary forms, with or without 10.\" modification, are permitted provided that the following conditions 11.\" are met: 12.\" 1. Redistributions of source code must retain the above copyright 13.\" notice, this list of conditions and the following disclaimer. 14.\" 2. Redistributions in binary form must reproduce the above copyright 15.\" notice, this list of conditions and the following disclaimer in the 16.\" documentation and/or other materials provided with the distribution. 17.\" 18.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28.\" POSSIBILITY OF SUCH DAMAGE. 29.\" 30.Dd April 20, 2004 31.Dt EXPR 1 32.Os 33.Sh NAME 34.Nm expr 35.Nd evaluate expression 36.Sh SYNOPSIS 37.Nm 38.Ar expression 39.Sh DESCRIPTION 40The 41.Nm 42utility evaluates 43.Ar expression 44and writes the result on standard output. 45.Pp 46All operators are separate arguments to the 47.Nm 48utility. 49Characters special to the command interpreter must be escaped. 50.Pp 51Operators are listed below in order of increasing precedence. 52Operators with equal precedence are grouped within { } symbols. 53.Bl -tag -width indent 54.It Ar expr1 Li | Ar expr2 55Returns the evaluation of 56.Ar expr1 57if it is neither an empty string nor zero; 58otherwise, returns the evaluation of 59.Ar expr2 . 60.It Ar expr1 Li \*[Am] Ar expr2 61Returns the evaluation of 62.Ar expr1 63if neither expression evaluates to an empty string or zero; 64otherwise, returns zero. 65.It Ar expr1 Li "{=, \*[Gt], \*[Ge], \*[Lt], \*[Le], !=}" Ar expr2 66Returns the results of integer comparison if both arguments are integers; 67otherwise, returns the results of string comparison using the locale-specific 68collation sequence. 69The result of each comparison is 1 if the specified relation is true, 70or 0 if the relation is false. 71.It Ar expr1 Li "{+, -}" Ar expr2 72Returns the results of addition or subtraction of integer-valued arguments. 73.It Ar expr1 Li "{*, /, %}" Ar expr2 74Returns the results of multiplication, integer division, or remainder of integer-valued arguments. 75.It Ar expr1 Li : Ar expr2 76The 77.Dq \&: 78operator matches 79.Ar expr1 80against 81.Ar expr2 , 82which must be a regular expression. 83The regular expression is anchored 84to the beginning of the string with an implicit 85.Dq ^ . 86.Pp 87If the match succeeds and the pattern contains at least one regular 88expression subexpression 89.Dq "\e(...\e)" , 90the string corresponding to 91.Dq "\e1" 92is returned; 93otherwise the matching operator returns the number of characters matched. 94If the match fails and the pattern contains a regular expression subexpression 95the null string is returned; 96otherwise 0. 97.It "( " Ar expr No " )" 98Parentheses are used for grouping in the usual manner. 99.El 100.Pp 101Additionally, the following keywords are recognized: 102.Bl -tag -width indent 103.It length Ar expr 104Returns the length of the specified string in bytes. 105.El 106.Pp 107Operator precedence (from highest to lowest): 108.Bl -enum -compact -offset indent 109.It 110parentheses 111.It 112length 113.It 114.Dq \&: 115.It 116.Dq "*" , 117.Dq "/" , 118and 119.Dq "%" 120.It 121.Dq "+" 122and 123.Dq "-" 124.It 125compare operators 126.It 127.Dq \*[Am] 128.It 129.Dq \Z'\*[tty-rn]'| 130.El 131.Sh EXIT STATUS 132The 133.Nm 134utility exits with one of the following values: 135.Bl -tag -width Ds -compact 136.It 0 137the expression is neither an empty string nor 0. 138.It 1 139the expression is an empty string or 0. 140.It 2 141the expression is invalid. 142.It \*[Gt]2 143an error occurred (such as memory allocation failure). 144.El 145.Sh EXAMPLES 146.Bl -enum 147.It 148The following example adds one to the variable a. 149.Dl a=`expr $a + 1` 150.It 151The following example returns zero, due to deduction having higher precedence 152than '\*[Am]' operator. 153.Dl expr 1 '\*[Am]' 1 - 1 154.It 155The following example returns the filename portion of a pathname stored 156in variable a. 157.Dl expr "/$a" Li : '.*/\e(.*\e)' 158.It 159The following example returns the number of characters in variable a. 160.Dl expr $a Li : '.*' 161.El 162.Sh STANDARDS 163The 164.Nm 165utility conforms to 166.St -p1003.2 . 167The 168.Ar length 169keyword is an extension for compatibility with GNU 170.Nm . 171.Sh AUTHORS 172Original implementation was written by 173.An J.T. Conklin 174.Aq jtc@NetBSD.org . 175It was rewritten for 176.Nx 1.6 177by 178.An Jaromir Dolecek 179.Aq jdolecek@NetBSD.org . 180.Sh NOTES 181The empty string 182.Dq 183cannot be matched with the intuitive: 184.Bd -literal -offset indent 185expr '' : '$' 186.Ed 187.Pp 188The reason is that the returned number of matched characters (zero) 189is indistinguishable from a failed match, so this returns failure. 190To match the empty string, use something like: 191.Bd -literal -offset indent 192expr x'' : 'x$' 193.Ed 194.Sh COMPATIBILITY 195This implementation of 196.Nm 197internally uses 64 bit representation of integers and checks for 198over- and underflows. 199It also treats / (division mark) and 200option '--' correctly depending upon context. 201.Pp 202.Nm 203on other systems (including 204.Nx 205up to and including 206.Nx 1.5 ) 207might not be so graceful. 208Arithmetic results might be arbitrarily 209limited on such systems, most commonly to 32 bit quantities. 210This means such 211.Nm 212can only process values between -2147483648 and +2147483647. 213.Pp 214On other systems, 215.Nm 216might also not work correctly for regular expressions where 217either side contains single forward slash, like this: 218.Bd -literal -offset indent 219expr / : '.*/\e(.*\e)' 220.Ed 221.Pp 222If this is the case, you might use // (double forward slash) 223to avoid confusion with the division operator: 224.Bd -literal -offset indent 225expr "//$a" : '.*/\e(.*\e)' 226.Ed 227.Pp 228According to 229.St -p1003.2 , 230.Nm 231has to recognize special option '--', treat it as an end of command 232line options and ignore it. 233Some 234.Nm 235implementations don't recognize it at all, others 236might ignore it even in cases where doing so results in syntax 237error. 238There should be same result for both following examples, 239but it might not always be: 240.Bl -enum -compact -offset indent 241.It 242expr -- : . 243.It 244expr -- -- : . 245.El 246Although 247.Nx 248.Nm 249handles both cases correctly, you should not depend on this behavior 250for portability reasons and avoid passing bare '--' as first 251argument. 252