What can affect the way Bash's "test" built-in works?
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.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Distribution: openSUSE, Raspbian, Slackware. Previous: MacOS, Red Hat, Coherent, Consensys SVR4.2, Tru64, Solaris
Posts: 2,800
Rep:
What can affect the way Bash's "test" built-in works?
I have a small library of shell variables and functions that I've used for some time and I'm finding that when I try to use them in one particular environment that one of the functions breaks. I tend to use a "Boolean" flag when writing scripts rather than setting strings to "T", "F", "TRUE", "FALSE" after running into too many cases where I got called in to debug someone's script and found that their "logical" test was failing due to a case mismatch. Instead what I normally use is the following in a file that I source near the top of a script:
Code:
TRUE="0 -eq 0"
FALSE="1 -eq 0"
function decode_boolean() {
test $*
if [ $? -eq 0 ]; then
echo "TRUE"
else
echo "FALSE"
fi
}
I haven't run into any problems using the two Boolean variables but recently I was working on a script where I thought it was important to display the value of a flag in a more human-friendly fashion and found that my "decode_boolean()" function always returned "TRUE".
I can source that library file from a terminal session define a couple of variables to $TRUE and $FALSE and correctly display their settings using "decode_boolean()". But... once I source my library file and try using that function inside another this other script, the "decode_boolean()" function gets hard-wired to returning "TRUE".
The script I'm working with is required to source a slew of other "libraries" full of environment variables and functions (and, frankly, cruft) and I'm wondering if there might be something in one of those files that could cause Bash's "test" built-in to break. For the moment I haven't been able to find anything that changes the way "test" would behave. (I'm having trouble thinking of a reason why one would ever want "test" to behave the way it currently is in that script.)
I've already tried prefixing the "test" with "builtin" in case someone, somewhere in one of the other files that I need to source has created a "test()" function that I haven't found. That did not help.
Ideas as to what I might look for?
(Then when this problem is solved, I can devote some time to figuring out why, in this script, in this environment, bash array assignments seem to not, you know, actually create arrays. I have noticed that one of the sourced files issues "unset IFS" and I suspect that is the problem with my array assignments but I'm unsure if I want to reset it to a sane value lest it break something in a spectacular way.)
Distribution: openSUSE, Raspbian, Slackware. Previous: MacOS, Red Hat, Coherent, Consensys SVR4.2, Tru64, Solaris
Posts: 2,800
Original Poster
Rep:
Quote:
Originally Posted by grail
How about pre-pending the script with set -xv and seeing what is being called and set.
Tried that and while it shows the contents of the sourced files, it's not terribly helpul. There are over 2500 lines of almost completely uncommented shell code that gets pulled in via multiple files when I source the "necessary" file needed for the project. (It's one ugly design; there's known dead code in these files but nobody wants to pull it out.) Any one of those files could be fouling things up. I'm just looking for known things in Bash that affect the way "test" works so I can look for those in these include/source files. Then I'm hoping I might be able to get in touch with their author(s) and ask "Uh... do we really need this? It's breaking things."
Tried that and while it shows the contents of the sourced files, it's not terribly helpul. There are over 2500 lines
Then make a standalone example to demonstrate the issue. Otherwise, we can only the tell you the problem might be somewhere in the 2500 lines that you didn't post.
Distribution: openSUSE, Raspbian, Slackware. Previous: MacOS, Red Hat, Coherent, Consensys SVR4.2, Tru64, Solaris
Posts: 2,800
Original Poster
Rep:
Quote:
Originally Posted by ntubski
Then make a standalone example to demonstrate the issue. Otherwise, we can only the tell you the problem might be somewhere in the 2500 lines that you didn't post.
I wasn't looking for someone to comb through all that sourced code (it's proprietary so I can't post it anyway). Just hoping someone would have seen something like this cause the behavior I'm seeing so I could narrow down my search.
Strictly speaking you have *2* occurrences of test in that fragment.
Any chance you are getting word-splitting ?. I'd use double quotes around the $*, and also [[ in lieu of [.
I'm aware of that. Proper usage of that function is to pass it a variable that's been set using $TRUE or $FALSE. Passing anything else and you're on your own. It is, after all, named decode_boolean(), not decode_arbitrary_text().
The darndest thing is that I can't write a script outside the environment that is set up using this giant source file that screws up the way it does when I have to source that file. The authors of that file tended to use typeset, export, and unset like they were being paid for each instance. I suspect that they've accidently disabled something along the way. Makes me wonder how much extra work they may have made for themselves by trying to be clever and unsetting things. Not looking forward to trying to find each and every place where they might have mucked up the way 'test' is working. The sourced file is either barely commented -- having a comment like "Function XYZ" at the top of function XYZ() is the type of highly informative commenting that's been employed -- and many of the comments that are there are there are apparently out of date. So... it's going to be a painful search. Hence this post/question; I was hoping to narrow the search parameters somewhat. Still hoping someone has an idea that can save me from a brute force, line-by-line search.
Tried that and while it shows the contents of the sourced files, it's not terribly helpul. There are over 2500 lines of almost completely uncommented shell code that gets pulled in via multiple files when I source the "necessary" file needed for the project.
If going through that much code, output to a file (with the -xv flags as suggested), and use grep to find any instances of 'test', 'set', and perhaps 'TRUE' and 'FALSE' for starters. Something after your file is sourced could be changing the definition of those variables. Maybe even in the environment as uppercase variable names should be 'reserved' for environment's use in good practice.
Last edited by goumba; 09-23-2016 at 08:10 AM.
Reason: My spelling sucks at times.
Actually, why not just put the set -xv right before the call to decode_boolean?
@OP, Ntubski is absolutely correct. Put the set -xv before the section you wish to debug and then put a set +xv after that section to only see what you wish.
Further, assign the outcome to variables and then you can echo the variables.
Note that you're citing this very huge environment issue as well as many lines of code. One thing to do is start with a clean environment and limit this code, only adding in verified portions and cleaning it up so that now you have properly maintained code.
Based on how you've described this, there's not necessarily a golden lance to fix this issue with a one liner, and if there is, I think all it will lead to is yet another problem a few weeks or months down the line, similarly causing you lengthy searching and debugging.
Distribution: openSUSE, Raspbian, Slackware. Previous: MacOS, Red Hat, Coherent, Consensys SVR4.2, Tru64, Solaris
Posts: 2,800
Original Poster
Rep:
Quote:
Originally Posted by syg00
Strictly speaking you have *2* occurrences of test in that fragment.
Any chance you are getting word-splitting ?. I'd use double quotes around the $*, and also [[ in lieu of [.
I've tried double quotes in the "test" line. No joy. I haven't tried the double brackets for testing the exit status. Shouldn't be necessary, I'd think, since I'm not using any extended tests. But... I'll give that a try. If that should work it'll be a bit sad as this function has worked for /years/ (heck, it's well into its 2nd /decade/) on various commercial UNIX flavors using Bourne, Korn, as well as Bash. The change would break some of that compatibility.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.