1.\" $NetBSD: expr.1,v 1.40 2025/03/15 22:01:16 rillig Exp $ 2.\" 3.\" Copyright (c) 2000, 2003, 2025 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 March 15, 2025 31.Dt EXPR 1 32.Os 33.Sh NAME 34.Nm expr 35.Nd evaluate expression 36.Sh SYNOPSIS 37.Nm 38.Ar operand ... 39.Sh DESCRIPTION 40The 41.Nm 42utility evaluates the expression consisting of the 43.Ar operand 44arguments and writes the result on standard output. 45.Pp 46Each operand is a separate argument 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 60if it is not empty; 61otherwise, returns zero. 62.It Ar expr1 Li & Ar expr2 63Returns the evaluation of 64.Ar expr1 65if neither expression evaluates to an empty string or zero; 66otherwise, returns zero. 67.It Ar expr1 Li "{=, >, >=, <, <=, !=}" Ar expr2 68Returns the result of the integer comparison if both arguments are integers; 69otherwise, returns the result of the string comparison 70using the locale-specific collation sequence. 71The result of each comparison is 1 if the specified relation is true, 72or 0 if the relation is false. 73.It Ar expr1 Li "{+, -}" Ar expr2 74Returns the result of addition or subtraction of integer-valued arguments. 75.It Ar expr1 Li "{*, /, %}" Ar expr2 76Returns the result of multiplication, integer division, or remainder 77of integer-valued arguments. 78.It Ar expr1 Li \&: Ar expr2 79The 80.Dq \&: 81operator matches 82.Ar expr1 83against 84.Ar expr2 , 85the latter must be a regular expression. 86The regular expression is anchored 87to the beginning of the string with an implicit 88.Dq ^ . 89.Pp 90If the match succeeds and the pattern contains at least one regular 91expression subexpression 92.Dq "\e(...\e)" , 93the string corresponding to 94.Dq "\e1" 95is returned; 96otherwise the matching operator returns the number of characters matched. 97If the match fails and the pattern contains a regular expression subexpression, 98the empty string is returned; 99otherwise 0. 100.It "( " Ar expr No " )" 101Parentheses are used for grouping in the usual manner. 102.El 103.Pp 104Additionally, the following keywords are recognized: 105.Bl -tag -width indent 106.It length Ar expr 107Returns the length of the specified string in bytes. 108.El 109.Pp 110Operator precedence (from highest to lowest): 111.Bl -enum -compact -offset indent 112.It 113parentheses 114.It 115length 116.It 117.Dq \&: 118.It 119.Dq "*" , 120.Dq "/" , 121and 122.Dq "%" 123.It 124.Dq "+" 125and 126.Dq "-" 127.It 128compare operators 129.It 130.Dq & 131.It 132.Dq \&| 133.El 134.Sh EXIT STATUS 135The 136.Nm 137utility exits with one of the following values: 138.Bl -tag -width Ds -compact 139.It 0 140the expression is neither an empty string nor 0. 141.It 1 142the expression is an empty string or 0. 143.It 2 144the expression is invalid. 145.It >2 146an error occurred (such as memory allocation failure). 147.El 148.Sh EXAMPLES 149.Bl -enum 150.It 151The following example adds one to variable 152.Dq a : 153.Dl a=`expr $a + 1` 154.It 155The following example returns zero, due to subtraction having higher precedence 156than the 157.Dq & 158operator: 159.Dl expr 1 '&' 1 - 1 160.It 161The following example returns the filename portion of a pathname stored 162in variable 163.Dq a : 164.Dl expr "/$a" Li : '.*/\e(.*\e)' 165.It 166The following example returns the number of characters in variable 167.Dq a : 168.Dl expr $a Li : '.*' 169.El 170.Sh COMPATIBILITY 171This implementation of 172.Nm 173internally uses 64 bit representation of integers and checks for 174over- and underflows. 175It also treats 176.Dq / 177(the division mark) and option 178.Dq -- 179correctly depending upon context. 180.Pp 181.Nm 182on other systems (including 183.Nx 184up to and including 185.Nx 1.5 ) 186might not be so graceful. 187Arithmetic results might be arbitrarily 188limited on such systems, most commonly to 32 bit quantities. 189This means such 190.Nm 191can only process values between -2147483648 and +2147483647. 192.Pp 193On other systems, 194.Nm 195might also not work correctly for regular expressions where 196either side contains 197.Dq / 198(a single forward slash), like this: 199.Bd -literal -offset indent 200expr / : '.*/\e(.*\e)' 201.Ed 202.Pp 203If this is the case, you might use 204.Dq // 205(a double forward slash) 206to avoid confusion with the division operator: 207.Bd -literal -offset indent 208expr "//$a" : '.*/\e(.*\e)' 209.Ed 210.Pp 211According to 212.St -p1003.2 , 213.Nm 214has to recognize the special option 215.Dq -- , 216treat it as a delimiter to mark the end of command 217line options, and ignore it. 218Some 219.Nm 220implementations do not recognize it at all; others 221might ignore it even in cases where doing so results in syntax 222error. 223There should be the same result for both following examples, 224but it might not always be: 225.Bl -enum -compact -offset indent 226.It 227expr -- : . 228.It 229expr -- -- : . 230.El 231Although 232.Nx 233.Nm 234handles both cases correctly, you should not depend on this behavior 235for portability reasons and avoid passing a bare 236.Dq -- 237as the first 238argument. 239.Sh STANDARDS 240The 241.Nm 242utility conforms to 243.St -p1003.2 . 244The 245.Ar length 246keyword is an extension for compatibility with GNU 247.Nm . 248.Sh HISTORY 249An 250.Nm 251utility first appeared in the Programmer's Workbench (PWB/UNIX). 252A public domain version of 253.Nm 254written by 255.An Pace Willisson 256.Aq pace@blitz.com 257appeared in 258.Bx 386 0.1 . 259.Sh AUTHORS 260Initial implementation by 261.An Pace Willisson Aq Mt pace@blitz.com 262was largely rewritten by 263.An -nosplit 264.An J.T. Conklin Aq Mt jtc@NetBSD.org . 265It was rewritten again for 266.Nx 1.6 267by 268.An -nosplit 269.An Jaromir Dolecek Aq Mt jdolecek@NetBSD.org . 270.Sh NOTES 271The empty string 272.Do Dc 273cannot be matched with the intuitive: 274.Bd -literal -offset indent 275expr '' : '$' 276.Ed 277.Pp 278The reason is that the returned number of matched characters (zero) 279is indistinguishable from a failed match, so this returns failure. 280To match the empty string, use something like: 281.Bd -literal -offset indent 282expr x'' : 'x$' 283.Ed 284