A Bourne-compatible alternative (${#string}
is POSIX but not Bourne (not that you're likely to ever come across a Bourne shell these days)):
case $string in
?????*) echo >&2 Too long; exit 1;;
*) echo OK
esac
Note that for both ${#string}
and ????
, whether it will be the number of bytes or characters will depend on the shell. Generally (and it's required by POSIX), it is the number of characters. But for some shells like dash
that are not multi-byte aware, it will be bytes instead.
With mksh
, you need set -o utf8-mode
(in UTF-8 locales) for it to understand multi-byte characters:
$ string=€€€ bash -c 'echo "${#string}"'
3
$ string=€€€ dash -c 'echo "${#string}"'
9
$ string=€€€ mksh -c 'echo "${#string}"'
9
$ string=€€€ mksh -o utf8-mode -c 'echo "${#string}"'
3
$ locale charmap
UTF-8
/bin/sh
. You should consider changing the shebang line to#!/bin/sh
so that it will be more portable and run in environments where bash isn't available. Plus,/bin/sh
might be a more lightweight shell like dash which isn't burdened with features meant for interactive use.dash
's${#string}
would give you the length in number of bytes instead of characters.