ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
Well, whaddaya know. That works. I hadn't thought about trying the backticks.
But I had considered the idea that the ')' was causing it. I decided that that couldn't be it, however, because I can surround it with parentheses to create a subshell.
Code:
(for i; do
case $i in
*$ext) echo $i;;
esac
done)
This gives no errors. It's only when I enclose it in $() that it breaks. Odd.
What, you can do that? I've never seen anything anywhere that said you could completely enclose the matching conditions in a case construct.
In any case, could this be a bug? I'd certainly consider it one. I don't think it should be necessary to materially alter the syntax of the commands inside of $(), particularly if it's not well-documented.
Edit: Did a little google searching, now that I know what's going on. Apparently it's a long-standing bug that's difficult to handle at the compiler level. And that appears to be the reason the fully-enclosed tests were introduced.
It would be nice if it were better-documented though. At least the ABSG could've mentioned it.
Edit two: This page has a chart that lists which shells can and can't handle various "unbalanced" parentheses statements inside $().
Last edited by David the H.; 08-21-2009 at 09:02 PM.
I wouldn't tell it's a shell bug as it was identified when the $() syntax was introduced by the korn shell a couple of decade ago, just a well known incompatibility between an old syntax and a newer one with a documented workaround.
I have been using the extra left parenthesis in all my case/esac statements for ages. It looks to me neater and more convenient than the original unbalanced design anyway. Despite being accepted by the standard, the newer shells accepting unbalanced parenthesis looks an ugly hack to me.
It is worth noticing the backquote syntax was considered as archaic in 1992 in the ksh documentation but is still widely used nowadays.
Debian has just included Bash v.4 in it's repositories (at least in unstable), and now the problem is gone. They've fixed this little error.
I did come across some new problems, however. One of my scripts uses an embedded here document, and it started spitting out an error after the upgrade. I was using something like this:
This worked fine in bash 3, but breaks in bash 4. Apparently it now chokes if there's anything else on the same line as the here statement's terminating string. Even comments mess it up. Moving the ")" to the next line lets it run.
Unfortunately though, there also seems to be a new, different bug. Any and all trailing newlines, in any kind of text output, now appear to be removed when inside $(). They not only disappear in the above code, but even when using something like echo.
Code:
#!/bin/bash
output="$(
echo "Sample text"
echo "Sample text"
echo "Sample text"
echo
echo -e "\n\n\n"
)"
echo "$output"
echo "======="
### The output ###
$ ./test.sh
Sample text
Sample text
Sample text
=======
$
Just about every test I've tried with text inside $() has shown the same effect. All trailing newlines disappear. Spaces and tabs do show up though.
I suppose I'll have to switch to using functions for generating large, formatted blocks of text instead.
All in all, though, bash 4 does seem to have some neat new features. I'm looking forward to playing with them.
Last edited by David the H.; 09-01-2009 at 11:59 AM.
Reason: fixed a mistake
The shell shall expand the command substitution by executing command in a subshell environment (see Shell Execution Environment) and replacing the command substitution (the text of command plus the enclosing "$()" or backquotes) with the standard output of the command, removing sequences of one or more <newline>s at the end of the substitution.
...
The here-document shall be treated as a single word that begins after the next <newline> and continues until there is a line containing only the delimiter and a <newline>, with no <blank>s in between.
Thank you for that information. To be fair, I didn't say that the first one was a bug, only that the behavior was different than before.
The removing all trailing newlines thing is a bit annoying though. It's my opinion that command substitution should, you know, substitute, the complete output of the embedded commands, no matter what they contain. Editing shouldn't be part of the process, even if it's just a few extra newlines. It should be up to the scripter to ensure that the substitution produces the desired output.
I was used to depending on the former behavior. Now I'm going to have to rewrite a couple of my old scripts.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.