Re: [A-Z], [:upper:]
Date:Thu, 28 Mar 2019 17:27:24 -0400 From:Greg Wooledge Message-ID: <20190328212724.aczkwjoyceeg6...@eeg.ccf.org> | You have two problems here. Well, four really. 2 really, I think... | First, your first example invokes platform-defined behavior. Technically, yes ... though unless something points to it being a locale problem (eg: if the example code and shell seem to peform flawlessly for everyone else) I think it is reasonable to assume the C locale (aka POSIX) locale for anything which doesn't say otherwise. And even ignoring that: | [A-Z] isn't safe to use unless ... That's true to an extent, but we know here that the intent is to match 'C' which is between A and Z in every locale in the universe. Variations on A might not be, variations on Z might not be, and there might be more than just the upper case English letters between A and Z, included in the ragne (even including things which are not letters at all, upper case or not, and lower case chars might be included) but we can assume that for any real locale, 'C' will be in that range (real as being one in use in the world, rather than one invented for the very purpose of not including C in the collating sequence between A and Z) So I think that problem can be overlooked/ignored. | Second, your second example should be using [[:upper:]] not [:upper:]. | You might be mixing up tr's syntax with glob/regex syntax. This, of course, is the real problem, and is (almost) all that really needed saying. My question however is this part from the original report: In version 4 [A-Z] is broken and [:upper:] works. In version 5, the situation is reversed. I don't see that (though in 4.4-something, rather than 4.3) and given the nature of the problem (incorrect usage), I don't understand how it is possible. I see the same results in both versions (with both the correct and incorrect usage). Unless... But because of that: | Also, you didn't tell us what result you got, or what result you | expected to see. This is also important. Giving actual in and out examples, cut and pasted from a real test run - however the cut/paste is done, doing the test with -x and directing stdout/stderr to a file, and including the file is one way, using "script" and including the typescript file is another, or cut/paste from an xterm (or any xxxterm) is another. (even including a jpeg of a photo of a screen image can work - though please, only as a last resort!) But everyone, please, never re-type the code/results in any bug-report - that almost always leads to problems, eg: if that was done here, and the missing [] pair were simply forgotten in the bug report, but had been used in the actual test.Then whatever is actually going wrong is something different, but without knowing what that is, no-one can possibly help. | And you forgot to quote. Really! That again! Here, unless one of A or B (or perhaps C, though as that's supposed to be removed, it shouldn't matter) is in IFS - in which case I think we'd be told - quoting makes no difference at all. Regardless of your views on the subject, not everything needs to be quoted. Quoting expansions where the content is unknown and the intent is for it to remain unchanged is the right thing to do. When the content of the variable is known, though it really is optional, and sometimes even wrong to quote. Failing do so in a test like this is not an issue at all. kre
Re: [A-Z], [:upper:]
> | And you forgot to quote. > > Really! That again! Here, unless one of A or B (or perhaps C, > though as that's supposed to be removed, it shouldn't matter) is in > IFS - in which case I think we'd be told - quoting makes no difference > at all. The example is clearly contrived just for the bug report and is a simplification of some existing code. That existing code probably uses a variable whose content comes from a file, or user input. That content may contain spaces. You appear to have strong feelings about this, but so do I, because I deal with failures to quote for hours upon hours, 5 days a week, in IRC. Really, it *is* necessary to hammer this point over and over again. If you're sick of hearing it, that's because you actually understand the issue. But a great number of the people posting to this list do not. Quoting is *the* number one issue in shell scripting. It cannot be reiterated enough. God knows we've tried, and it's still not enough.
Can not declare a local variable if an global ro-variable exists with the same name
Configuration Information [Automatically generated, do not change]: Machine: x86_64 OS: linux-gnu Compiler: gcc Compilation CFLAGS: -DPROGRAM='bash' -DCONF_HOSTTYPE='x86_64' -DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='x86_64-redhat-linux-gnu' -DCONF_VENDOR='redhat' -DLOCALEDIR='/usr/share/locale' -DPACKAGE='bash' -DSHELL -DHAVE_CONFIG_H -I. -I. -I./include -I./lib -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic uname output: Linux ocde150562 3.10.0-957.10.1.el7.x86_64 #1 SMP Thu Feb 7 07:12:53 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux Machine Type: x86_64-redhat-linux-gnu Bash Version: 4.2 Patch Level: 46 Release Status: release Description: If I declare a global read-only variable and I try to declare a local variable with that name, I can not create the local variable. I expect that local variables can be declared independently for the global variables. Repeat-By: $ declare -r var=55 $ myfunction() { > local var=11 > echo "\$var=$var" > return 0 > } $ myfunction bash: local: var: readonly variable $var=55
Re: [A-Z], [:upper:]
> | [A-Z] isn't safe to use unless ... > > That's true to an extent, but we know here that the intent is to > match 'C' which is between A and Z in every locale in the universe. > Variations on A might not be, variations on Z might not be, and there > might be more than just the upper case English letters between A and Z, > included in the ragne (even including things which are not letters at > all, upper case or not, and lower case chars might be included) but we > can assume that for any real locale, 'C' will be in that range (real as > being one in use in the world, rather than one invented for the very > purpose of not including C in the collating sequence between A and Z) So, embracing and extending your assumptions, we can also claim that the letter T is between A and Z in every locale in the universe, right? wooledg:~$ printf %s\\n {A..Z} | LC_COLLATE=et_EE.utf8 sort | tr '\n' ' ' A B C D E F G H I J K L M N O P Q R S Z T U V W X Y Isn't real life FUN? But perhaps you're right about the letter C specifically. Maybe that one letter just happens to lie between A and Z in every locale on Earth. I don't happen to know of any counter-examples... yet. Now, for the original poster: the meaning of [A-Z] and [a-z] did in fact change between bash 4 and bash 5. wooledg:~$ bash-4.4 -c 'LC_COLLATE=et_EE.utf8; [[ T = [A-Z] ]] && echo match' wooledg:~$ bash-5.0 -c 'LC_COLLATE=et_EE.utf8; [[ T = [A-Z] ]] && echo match' match This is yet one more reason you can't rely on [A-Z] or [a-z] to work as expected in scripts. Even between different versions of bash, within the same locale, on the same computer, it doesn't behave consistently. I strongly recommend switching to [[:upper:]] and friends, unless you always work in the C locale (and explicitly set it in your scripts).
Re: Can not declare a local variable if an global ro-variable exists with the same name
On Wed, Mar 27, 2019 at 02:06:51PM +0100, joerg...@snafu.de wrote: > If I declare a global read-only variable and I try to declare a local > variable with that name, I can not create > the local variable. > I expect that local variables can be declared independently for the > global variables. The purpose of the readonly flag on shell variables is to support the restricted shell. I will pause while you laugh and/or cry. In order for a restricted shell to have half a chance of working (keeping the user imprisoned), the PATH variable has to be immutable. If the user can modify PATH, they can run a real shell and escape. So, in rbash and friends, PATH gets marked readonly, and bash treats the readonly flag as sacrosanct. Allowing a user to work around it simply by creating a function would let them break out of the restricted shell too easily. Readonly is forever.
Re: Can not declare a local variable if an global ro-variable exists with the same name
On 3/27/19 9:06 AM, joerg...@snafu.de wrote: > Bash Version: 4.2 > Patch Level: 46 > Release Status: release > > Description: > If I declare a global read-only variable and I try to declare a local > variable with that name, I can not create > the local variable. > I expect that local variables can be declared independently for the > global variables. Yes, it's been that way for about as long as bash has had local variables. The idea is that variables are readonly for a reason, and you shouldn't just be able to circumvent that with a local variable declaration. It's similar to the error you get if you try to assign a value to a readonly variable using an assignment statement that precedes a command. Chet -- ``The lyf so short, the craft so long to lerne.'' - Chaucer ``Ars longa, vita brevis'' - Hippocrates Chet Ramey, UTech, CWRUc...@case.eduhttp://tiswww.cwru.edu/~chet/
Re: [A-Z], [:upper:]
Date:Fri, 29 Mar 2019 08:41:49 -0400 From:Greg Wooledge Message-ID: <20190329124148.a3t3xkze4btsk...@eeg.ccf.org> | But perhaps you're right about the letter C specifically. I was, because that was the character of relevance in the bug report, and solving (or inventigating) the actual problems reported is what ought to be done - not imaginng what the underlying problem might be, and guessing at what might be the cause of that. | Now, for the original poster: the meaning of [A-Z] and [a-z] did in | fact change between bash 4 and bash 5. Sure, but as the character was C, this doesn't matter. Just as in generla using [A-Z] isn't always a very good idea - here it did not matter. >From the earlier message: | The example is clearly contrived just for the bug report and is a | simplification of some existing code. Yes, most likely. But all we can reliably do is investigate the actual case that is stated to fail. Having a complex test case simplified down to the simplest case that fails that can be found is always helpful - and when users can do that, it is good. But we must resist: | That existing code probably that's just guesswork and is an extreme waste of time. If the example in the bug report hadn't been properly tested, we should get an update, with the actual issue in it. If that was really it, then we know what the problem was (but not the bash4/5 difference reported). wool...@eeg.ccf.org said: | Quoting is *the* number one issue in shell scripting. It cannot be | reiterated enough. God knows we've tried, and it's still not enough. Yes, I know it is a very common problem.But by overdoing the complaints - inventing quoting issues when there are none - you're doing the message a disservice. The users are not all complete idiots - they know (occasionally) that quoting is not needed, and when you tell them that they should add quotes they ignore you, then, and possiblt, also some other time when quotes are really needed. Keep the "should be quoted" for examples where it is actually required, and just ignore that issue when it clearly is not. Then people will take the message more seriously. Or in other words, evangalists get ignored by most rational people, whatever the topic. kre