LinuxQuestions.org
Review your favorite Linux distribution.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 09-22-2016, 01:48 PM   #1
rnturn
Senior Member
 
Registered: Jan 2003
Location: Illinois (SW Chicago 'burbs)
Distribution: openSUSE, Raspbian, Slackware. Previous: MacOS, Red Hat, Coherent, Consensys SVR4.2, Tru64, Solaris
Posts: 2,800

Rep: Reputation: 550Reputation: 550Reputation: 550Reputation: 550Reputation: 550Reputation: 550
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.)

TIA for any hints anyone has.
 
Old 09-22-2016, 02:27 PM   #2
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,007

Rep: Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191
How about pre-pending the script with set -xv and seeing what is being called and set.
 
Old 09-22-2016, 04:57 PM   #3
rnturn
Senior Member
 
Registered: Jan 2003
Location: Illinois (SW Chicago 'burbs)
Distribution: openSUSE, Raspbian, Slackware. Previous: MacOS, Red Hat, Coherent, Consensys SVR4.2, Tru64, Solaris
Posts: 2,800

Original Poster
Rep: Reputation: 550Reputation: 550Reputation: 550Reputation: 550Reputation: 550Reputation: 550
Quote:
Originally Posted by grail View Post
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."
 
Old 09-22-2016, 06:40 PM   #4
keefaz
LQ Guru
 
Registered: Mar 2004
Distribution: Slackware
Posts: 6,552

Rep: Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872
If you pass a non empty variable to decode_boolean() it will echo "TRUE" if the variable doesn't contain an expression that will make test fails

eg:
decode_boolean "bla" => TRUE
decode_boolean "" => FALSE
 
Old 09-22-2016, 06:55 PM   #5
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian, Arch
Posts: 3,780

Rep: Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081
Quote:
Originally Posted by rnturn View Post
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.
 
Old 09-22-2016, 10:16 PM   #6
rnturn
Senior Member
 
Registered: Jan 2003
Location: Illinois (SW Chicago 'burbs)
Distribution: openSUSE, Raspbian, Slackware. Previous: MacOS, Red Hat, Coherent, Consensys SVR4.2, Tru64, Solaris
Posts: 2,800

Original Poster
Rep: Reputation: 550Reputation: 550Reputation: 550Reputation: 550Reputation: 550Reputation: 550
Quote:
Originally Posted by ntubski View Post
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.
 
Old 09-22-2016, 10:31 PM   #7
syg00
LQ Veteran
 
Registered: Aug 2003
Location: Australia
Distribution: Lots ...
Posts: 21,126

Rep: Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120
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 [.
 
Old 09-22-2016, 10:33 PM   #8
rnturn
Senior Member
 
Registered: Jan 2003
Location: Illinois (SW Chicago 'burbs)
Distribution: openSUSE, Raspbian, Slackware. Previous: MacOS, Red Hat, Coherent, Consensys SVR4.2, Tru64, Solaris
Posts: 2,800

Original Poster
Rep: Reputation: 550Reputation: 550Reputation: 550Reputation: 550Reputation: 550Reputation: 550
Quote:
Originally Posted by keefaz View Post
If you pass a non empty variable to decode_boolean() it will echo "TRUE" if the variable doesn't contain an expression that will make test fails

eg:
decode_boolean "bla" => TRUE
decode_boolean "" => FALSE
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.
 
Old 09-23-2016, 06:26 AM   #9
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,862
Blog Entries: 1

Rep: Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869
It's only the name and the working of the function I suggest to change:
Code:
test_echo () {
   local RC

   test "$@"
   RC=$?
   if [ $RC -eq 0 ]; then
      printf "'%s' is 'TRUE'\n" "$*"
   else
      printf "'%s' is 'FALSE'\n" "$*"
   fi
   return $RC
}
usage:
Code:
test_echo 'ab u' = 'a bu'
test_echo 'ab u' = 'ab u'

if test_echo 'a' '<' 'b'; then
    printf 'a lesser than b\n'
else
    printf 'a not lesser than b\n'
fi

Last edited by NevemTeve; 09-23-2016 at 10:19 AM.
 
Old 09-23-2016, 07:24 AM   #10
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian, Arch
Posts: 3,780

Rep: Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081
Quote:
Originally Posted by rnturn View Post
Tried that and while it shows the contents of the sourced files, it's not terribly helpul.
Actually, why not just put the set -xv right before the call to decode_boolean?
 
Old 09-23-2016, 07:42 AM   #11
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 21,838

Rep: Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308
set -xv is the best tip I can suggest too. That is really helpful, you can see how your code is interpreted and executed (line by line).
 
Old 09-23-2016, 08:04 AM   #12
goumba
Senior Member
 
Registered: Dec 2009
Location: New Jersey, USA
Distribution: Fedora, OpenSUSE, FreeBSD, OpenBSD, macOS (hack). Past: Debian, Arch, RedHat (pre-RHEL).
Posts: 1,335
Blog Entries: 7

Rep: Reputation: 402Reputation: 402Reputation: 402Reputation: 402Reputation: 402
Quote:
Originally Posted by rnturn View Post
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.
 
Old 09-23-2016, 08:54 AM   #13
rtmistler
Moderator
 
Registered: Mar 2011
Location: USA
Distribution: MINT Debian, Angstrom, SUSE, Ubuntu, Debian
Posts: 9,882
Blog Entries: 13

Rep: Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930
Quote:
Originally Posted by ntubski View Post
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.
 
Old 09-23-2016, 11:00 AM   #14
rnturn
Senior Member
 
Registered: Jan 2003
Location: Illinois (SW Chicago 'burbs)
Distribution: openSUSE, Raspbian, Slackware. Previous: MacOS, Red Hat, Coherent, Consensys SVR4.2, Tru64, Solaris
Posts: 2,800

Original Poster
Rep: Reputation: 550Reputation: 550Reputation: 550Reputation: 550Reputation: 550Reputation: 550
Quote:
Originally Posted by syg00 View Post
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.
 
Old 09-23-2016, 11:18 AM   #15
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,862
Blog Entries: 1

Rep: Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869
Kindly check the difference between $* and "$*" and "$@" -- they are all different things.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
This possible in Bash? Something like "echo test > ./newdirA/newdirB/newfile" Shay Linux - General 1 07-11-2011 09:50 AM
How to write a simple BASH script to "test if have folowing files, than delete."? hocheetiong Programming 10 10-01-2009 12:17 PM
bash "do-while" post-test syntax orange.toaster Programming 3 07-07-2009 04:26 PM
my var in bash doesn't work: ARRAY_$a_$b="test" SlackerJack Linux - General 3 01-13-2008 03:45 AM
LFS 6.2 Ch. 6.14 - 2nd Coreutils test returns "/bin.bash: No such file or directory" 0graham0 Linux From Scratch 2 08-23-2007 06:32 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 04:26 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration