LinuxQuestions.org
Share your knowledge at the LQ Wiki.
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-20-2019, 03:13 AM   #1
hazel
Senior Member
 
Registered: Mar 2016
Location: Harrow, UK
Distribution: LFS, AntiX, Slackware
Posts: 3,378
Blog Entries: 9

Rep: Reputation: 1884Reputation: 1884Reputation: 1884Reputation: 1884Reputation: 1884Reputation: 1884Reputation: 1884Reputation: 1884Reputation: 1884Reputation: 1884Reputation: 1884
Why do scripting languages use a reverse convention for indicating TRUE and FALSE?


In C, numerals have a boolean significance. Zero is FALSE as are its equivalents: the NULL pointer and the NULL character. Non-zero numbers are TRUE; in practice TRUE=1. This is clearly intuitive. Computers work in binary: 1 and 0, on and off, set and unset, pulse or no pulse. It seems logical that if there is no pulse when a pulse was expected, that signifies FALSE.

But when calling exit() in your program, you pass 0 for success and 1 for error or failure. That's because a script may need to analyse the behaviour of your program and all Unix scripting languages use that convention rather than the more intuitive one. I assume there must be some historical reason for that. Does anyone know how it originated?

Last edited by hazel; 09-20-2019 at 03:14 AM.
 
Old 09-20-2019, 03:26 AM   #2
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 3,860

Rep: Reputation: 1344Reputation: 1344Reputation: 1344Reputation: 1344Reputation: 1344Reputation: 1344Reputation: 1344Reputation: 1344Reputation: 1344Reputation: 1344
> But when calling exit() in your program, you pass 0 for success and 1 for error or failure.

Well, these aren't logical values, they are status-codes: 0 means success, other values are error codes. As many different errors may happen, it is quite plausible. (Edit: IBM /360 mainframe's programs often used these values: 0=OK, 4=Warning, 8=Error, 12+=FatalError)

(I think it would be easier if program '/bin/true' would called 'success' and '/bin/false' would be 'fail'.)

Last edited by NevemTeve; 09-20-2019 at 03:31 AM.
 
1 members found this post helpful.
Old 09-20-2019, 04:23 AM   #3
ehartman
Member
 
Registered: Jul 2007
Location: Delft, The Netherlands
Distribution: Slackware
Posts: 952

Rep: Reputation: 496Reputation: 496Reputation: 496Reputation: 496Reputation: 496
Quote:
Originally Posted by hazel View Post
But when calling exit() in your program, you pass 0 for success and 1 for error or failure.
No, you pass an error code (int), not a boolean:
Code:
void _exit(int status);
     The value status & 0377 is returned to the parent process as the process's
     exit status, and can be collected using one of the wait(2) family of calls.
(from the man page of the system call _exit(2))
So the error code is limited to the range 0(=successfull exit) thru 0377 octal (255 decimal), so is in fact an UNsigned byte.
As the shell used does the "wait" call, it will get this 0 to 255 exit value from the application and that value is what the scripts are testing for.
 
1 members found this post helpful.
Old 09-20-2019, 05:26 AM   #4
hazel
Senior Member
 
Registered: Mar 2016
Location: Harrow, UK
Distribution: LFS, AntiX, Slackware
Posts: 3,378

Original Poster
Blog Entries: 9

Rep: Reputation: 1884Reputation: 1884Reputation: 1884Reputation: 1884Reputation: 1884Reputation: 1884Reputation: 1884Reputation: 1884Reputation: 1884Reputation: 1884Reputation: 1884
So "0" means "No errors". Yes, that would make sense. I think what confused me is that conditional structures in scripts (for example if...elif...else...fi in bash) treat the exit codes of programs in a boolean way and you can do boolean operations on them. They behave like TRUE and FALSE.
 
Old 09-20-2019, 05:28 AM   #5
freemedia2018
Member
 
Registered: Mar 2019
Distribution: various automated remasters
Posts: 152
Blog Entries: 2

Rep: Reputation: 108Reputation: 108
You can think of it as a boolean flag IS_ERROR

0 = FALSE | nonzero = TRUE

It makes sense to have IS_ERROR rather than IS_SUCCESSFUL because you dont need to be specific about "there is no error".

So 0 is the only FALSE but nonzero lets you be specific about things that can go into more detail (which nonzero) ... also

C isnt different, so this isnt about scripting languages: https://en.wikipedia.org/wiki/Exit_status#C_language

Last edited by freemedia2018; 09-20-2019 at 05:31 AM.
 
Old 09-20-2019, 05:58 AM   #6
rtmistler
Moderator
 
Registered: Mar 2011
Location: MA, USA
Distribution: MINT Debian, Angstrom, SUSE, Ubuntu, Debian
Posts: 8,038
Blog Entries: 13

Rep: Reputation: 3488Reputation: 3488Reputation: 3488Reputation: 3488Reputation: 3488Reputation: 3488Reputation: 3488Reputation: 3488Reputation: 3488Reputation: 3488Reputation: 3488
I suggest that one be extremely cautious assuming just values of 1 and 0. Some commands return other than just those two values. Yes a non-zero value means a problem, however it usually is beneficial to understand the difference between one error and another.
 
1 members found this post helpful.
Old 09-20-2019, 06:09 AM   #7
Firerat
Senior Member
 
Registered: Oct 2008
Distribution: Debian sid
Posts: 2,320

Rep: Reputation: 635Reputation: 635Reputation: 635Reputation: 635Reputation: 635Reputation: 635
what everyone else says...

0 = nothing to report
1 = bust
2 = bust with more detail
...
404 = the page you are looking for does not exist


and you can pass error codes
Code:
#!/bin/bash
errorme() {
return $1
}
report() {
case $1 in
    0) echo "something went very very wrong"
        ;;
    1) echo "yeah, it broke";;
    2) echo "ok, so it is the thingy";;
    3) echo "the thingy + the watsit";;
    4) echo "bash did it";;
    *) echo "unknown error"
       printf "\t%02d\t" ${count}
        return 3;;
esac
return 0
}
count=0
for i in {0..5} {5..0}
do
    ((count++))
    printf "%02d\t" ${count}
    if (errorme $i )
    then
        echo ok
    else
        report $? || report $?
    fi
done

Last edited by Firerat; 09-20-2019 at 06:14 AM. Reason: changed the unknown error return code from 1 to 3, demos better
 
1 members found this post helpful.
Old 09-20-2019, 06:15 AM   #8
bigearsbilly
Senior Member
 
Registered: Mar 2004
Location: england
Distribution: Slack, Debian, Mint, Puppy, Raspbian
Posts: 3,465

Rep: Reputation: 220Reputation: 220Reputation: 220
It's because you are returning a useful value on error to the caller. All processes, not just shell scripts return a value, 0 means OK.

It's actually a combination of things, including if the process was killed etc,

https://linux.die.net/man/2/waitpid

https://en.wikipedia.org/wiki/Exit_status
 
1 members found this post helpful.
Old 09-20-2019, 06:22 AM   #9
ehartman
Member
 
Registered: Jul 2007
Location: Delft, The Netherlands
Distribution: Slackware
Posts: 952

Rep: Reputation: 496Reputation: 496Reputation: 496Reputation: 496Reputation: 496
Quote:
Originally Posted by hazel View Post
So "0" means "No errors". Yes, that would make sense.
For instance in a program of mine (for freedb CD info database) I use
Code:
 perror("Open error");
 return(1);

 perror("Stat error");
 return(2);

and at the end   return(0);
The C standard specifies two constants, EXIT_SUCCESS and EXIT_FAILURE, that may be passed to exit() to indicate successful or unsuccessful termination, respectively.
(and, of course, these have as value 0 resp 1).

Quote:
I think what confused me is that conditional structures in scripts (for example if...elif...else...fi in bash) treat the exit codes of programs in a boolean way and you can do boolean operations on them. They behave like TRUE and FALSE.
Yeah, but bash uses TWO different constructions for exit codes then for logical expressions:
Code:
    if <commandline>
tests for the exit status OF the command, so 0 means OK, no errors
   if [ <logical expression> ]
(note the []) tests a logical expression for TRUE or FALSE
 
Old 09-20-2019, 07:48 AM   #10
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian, Arch
Posts: 3,508

Rep: Reputation: 1811Reputation: 1811Reputation: 1811Reputation: 1811Reputation: 1811Reputation: 1811Reputation: 1811Reputation: 1811Reputation: 1811Reputation: 1811Reputation: 1811
Quote:
Originally Posted by ehartman View Post
Yeah, but bash uses TWO different constructions for exit codes then for logical expressions:
Code:
    if <commandline>
tests for the exit status OF the command, so 0 means OK, no errors
   if [ <logical expression> ]
(note the []) tests a logical expression for TRUE or FALSE
I find it more useful to think of bash as only having the first construct for exit codes, and [ <logical expression> ] is simply a particular example of <commandline>.
 
Old 09-20-2019, 08:15 AM   #11
hazel
Senior Member
 
Registered: Mar 2016
Location: Harrow, UK
Distribution: LFS, AntiX, Slackware
Posts: 3,378

Original Poster
Blog Entries: 9

Rep: Reputation: 1884Reputation: 1884Reputation: 1884Reputation: 1884Reputation: 1884Reputation: 1884Reputation: 1884Reputation: 1884Reputation: 1884Reputation: 1884Reputation: 1884
Quote:
Originally Posted by ntubski View Post
I find it more useful to think of bash as only having the first construct for exit codes, and [ <logical expression> ] is simply a particular example of <commandline>.
Well, that's the point I was making. Bash treats exit codes as booleans. Though as far as I can remember, the [ <logical expression> ] construct is actually "test(logical expression)" where test is the old Bourne shell test command. Bash symlinks "[" to "test". That's why you have to have a space after it.

I remember reading in some programming guide or other that it's bad practice to have multiple error codes for different kinds of errors because nobody wants to have to look them up. The obvious exception is grep, where failure to find a string isn't really an error at all if the string isn't there. So grep has 0 for finding the string, 1 for not finding it and 2 for genuine errors such as bad syntax in search string.
 
Old 09-20-2019, 08:21 AM   #12
ehartman
Member
 
Registered: Jul 2007
Location: Delft, The Netherlands
Distribution: Slackware
Posts: 952

Rep: Reputation: 496Reputation: 496Reputation: 496Reputation: 496Reputation: 496
Quote:
Originally Posted by hazel View Post
where test is the old Bourne shell test command.
Which even exists as its own external command (see "man test").
So "if [ ..." can be written too as "test ...", which I often use as a one-line if:
Code:
test -d $BASEDIR || mkdir $BASEDIR
or even
test $? -eq 0 && rm -f $SOURCE || echo "Error in convertion of $SOURCE"
 
Old 09-20-2019, 08:28 AM   #13
hazel
Senior Member
 
Registered: Mar 2016
Location: Harrow, UK
Distribution: LFS, AntiX, Slackware
Posts: 3,378

Original Poster
Blog Entries: 9

Rep: Reputation: 1884Reputation: 1884Reputation: 1884Reputation: 1884Reputation: 1884Reputation: 1884Reputation: 1884Reputation: 1884Reputation: 1884Reputation: 1884Reputation: 1884
OK. "&&" and "||" are boolean operators, aren't they? So how does that work if the exit codes from test and rm are just integers?
 
Old 09-20-2019, 08:29 AM   #14
Firerat
Senior Member
 
Registered: Oct 2008
Distribution: Debian sid
Posts: 2,320

Rep: Reputation: 635Reputation: 635Reputation: 635Reputation: 635Reputation: 635Reputation: 635
read

https://mywiki.wooledge.org/BashGuid...ndConditionals


but the quick answer is, you use case
I wonder if I can find an example?

here is one I made earlier
https://www.linuxquestions.org/quest...1/#post6038551

Last edited by Firerat; 09-20-2019 at 08:31 AM.
 
1 members found this post helpful.
Old 09-20-2019, 08:43 AM   #15
ehartman
Member
 
Registered: Jul 2007
Location: Delft, The Netherlands
Distribution: Slackware
Posts: 952

Rep: Reputation: 496Reputation: 496Reputation: 496Reputation: 496Reputation: 496
Quote:
Originally Posted by hazel View Post
OK. "&&" and "||" are boolean operators, aren't they?
Yes, but they work on EXIT-codes, so for them 0 means success and anything else means failure (of the previous command).
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

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
if statement ignoring true/false and proceeding anyway. Goblin_C_Noob Programming 4 03-30-2008 09:56 AM
comparison is always true/false jubaitca Programming 20 11-05-2006 06:55 PM
true or false? alaios Programming 7 07-16-2005 10:54 AM
Return true or false if I have ping reply Menestrel Programming 4 11-29-2004 12:40 AM

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

All times are GMT -5. The time now is 10:52 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
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration