svn commit: r282672 - head/etc/rc.d

Devin Teske dteske at FreeBSD.org
Mon May 11 19:37:32 UTC 2015


> On May 11, 2015, at 12:18 PM, Brooks Davis <brooks at freebsd.org> wrote:
> 
> On Sun, May 10, 2015 at 03:45:48PM -0400, John Baldwin wrote:
>> 
>>> On May 8, 2015, at 19:36, Xin LI <delphij at FreeBSD.org> wrote:
>>> 
>>> Author: delphij
>>> Date: Fri May  8 23:36:31 2015
>>> New Revision: 282672
>>> URL: https://svnweb.freebsd.org/changeset/base/282672
>>> 
>>> Log:
>>> Always convert uuid to lower case.
>>> 
>>> MFC after:    2 weeks
>>> 
>>> Modified:
>>> head/etc/rc.d/hostid
>>> 
>>> Modified: head/etc/rc.d/hostid
>>> ==============================================================================
>>> --- head/etc/rc.d/hostid    Fri May  8 23:29:42 2015    (r282671)
>>> +++ head/etc/rc.d/hostid    Fri May  8 23:36:31 2015    (r282672)
>>> @@ -58,7 +58,7 @@ hostid_set()
>>> 
>>> valid_hostid()
>>> {
>>> -    uuid=$1
>>> +    uuid=$(echo $1 | tr '[:upper:]' '[:lower:]')
>> 
>> tr is in /usr/bin so this breaks systems with a separate /usr.  Perhaps you could use dd with conv=lcase instead?
> 
> Alterntively, a shell function "ltr" exists in rc.subr for this purpose.
> 

ltr would not work in this situation, for multiple reasons.

1. ltr doesn’t support character classes
2. ltr is for replacing one or more characters (cannot be a class) with a single string (of variable length, 0+).

In /etc/networks.subr you can see an example usage of ltr:

287 <https://svnweb.freebsd.org/base/head/etc/network.subr?view=markup#l287>	        _punct=".-/+"
288 <https://svnweb.freebsd.org/base/head/etc/network.subr?view=markup#l288>	        ltr ${_if} "${_punct}" '_' _if

The result of this is to take a value of (for example) foo.bar and replace
any occurrences of period, minus, forward slash, or plus with instead
a single underscore. The result is stuffed into the variable “_if” (over-
writing previous contents which may have contained aforementioned
characters replaced with underscore).

An attempt to use ltr in the below fashion:

	ltr $string ‘[:lower:]’ ‘[:upper:]’ somevar

would surely fail.

While it is indeed *possible* to write a find/replace function in native-
shell that supports character classes, it would not be a small function.
The primary issue is that you need to know what the character that
matched the class and there aren’t any built-ins that provide this info.

For example:

	case “$src” in *[[:lower:]]*)

will trigger when you have a lower-case character that needs conversion
to upper-case (or opposite if using *[[:upper:]]*) BUT you won’t know
what the character was that you matched (so how can you know which
upper-case character to supplant)?

The function will have to resort to complicated substring mechanics or
any other seldom known procedure.

I’ll have a noodle on it and see what I can come up with. It’s not exactly
immediately coming to me how to do this in any simple fashion while
maintaining efficiency (read: by not iterating over every single character
and also by not having a giant massive case statement with every letter
spelled out — coming up with a solution that embraces the use of the
character class I would believe to be more efficient).
— 
Devin


More information about the svn-src-all mailing list