I'm just starting to learn shell, and I felt really puzzled when I got a syntax error in this simple code :
str="Hello world!"
echo $(expr length "$str")
But this code can work on Ubantu actually. Is it because my bash version is outdated? Or is it a problem with the MacOS system?
I have updated my bash version, now it is GNU bash 5.1.16, but this problem still exists. I'm really confused right now.
CodePudding user response:
expr
on MacOS does not accept the argument length
. The man page contains this rather oblique passage:
According to the POSIX standard, the use of string arguments
length
,substr
,index
, ormatch
produces undefined results. In this version ofexpr
, these arguments are treated just as their respective string values.
In other words, expr length
simply returns length
and expr length "$str"
is a syntax error because expr
only accepts a single argument.
This isn't a problem really, because Bash scripts should basically never need to use expr
at all. Bash has built-in facilities which replace more or less all of the legacy expr
logic.
To get the length of a string in Bash, try
${#str}
For more, probably start with the parameter expansions in Bash.
expr
is an OS utility which is independent of your shell, so it doesn't really make any difference which version of Bash you are using, or in fact whether you are using a shell at all.
If you find yourself in a situation where you need to get a string's length portably in a POSIX sh
/ Bourne shell script, perhaps resort to Awk.
len=$(printf '%s\n' "$str" | awk '{ print(length($0)) }')
(This will print multiple numbers if str
contains multiple lines. It's not hard to change it if you need to find the total length of a string with embedded newlines, but I'm guessing we don't need to go there.)