'tr' mystery

One of the scripts in Woof has suddenly gone crazy. I found the cause: the 'tr' utility has suddenly developed an abnormality. The script uses 'tr' to convert all lower-case letters to upper, like this:

# echo 'abc' | tr [a-z] [A-Z]

...well, the output used to be 'ABC', but now it has become 'abc'. In other words, tr is just passing the characters through unchanged:

# echo 'abc' | tr [a-z] [A-Z]

I tried with the latest 1.16.0 'busybox' executable, same problem.

I rebooted with "pfix=ram" and 'tr' works. I ran my Woof script and 'tr' becomes broken. I have used this '2createpackages' script many times without this problem. I am so puzzled.

Ah, if I open a new terminal, 'tr' works again. More specifically, if I open another terminal in the same Woof directory as my script, 'tr' is broken. Open a terminal anywhere else, 'tr' works.

However, if I do it this way, tr comes good again:

# echo 'abc' | tr '[a-z]' '[A-Z]'

I put the single-quotes into my script, and it is now working. Yeah, but why?????

Posted on 6 Feb 2010, 19:41


Posted on 7 Feb 2010, 6:56 by cli_user
quoting tr arguments
Single quotes work because they tell the shell not to interpret the character classes '[a-z]'. It could be seeing a tr builtin in the shell vs a busybox app. Having to quote tr arguments has been a standard for years. Check for any kind of default regex behavior in your shell as well.

Posted on 7 Feb 2010, 14:56 by Purplebelly
From info coreutils 'tr invocation'
GNU `tr' does not support the System V syntax that uses square

brackets to enclose ranges. Translations specified in that format
sometimes work as expected, since the brackets are often
transliterated to themselves. However, they should be avoided
because they sometimes behave unexpectedly. For example, `tr -d
'[0-9]'' deletes brackets as well as digits.

Posted on 8 Feb 2010, 10:43 by jeffrey
tr explanation
Single quotes are necessary on the arguments to tr because those arguments may otherwise be changed by the shell. So if you use "tr [a-z] [A-Z]" and there are no single letter files in the current directory it will work as you expect. But say you have a file called "a" and another called "Z". Then the shell will perform filename expansion on your tr command giving "tr a Z". Then "abc" will be translated to "Zbc". Probably not what you want. So the tr arguments must always be quoted if they might otherwise be modified by shell filename expansion (which is normally the case).