LinuxQuestions.org
Help answer threads with 0 replies.
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 03-03-2012, 04:45 AM   #1
leslie_jones
Member
 
Registered: Sep 2011
Posts: 130

Rep: Reputation: Disabled
Unhappy Shell Script 101: TEST


I feel a bit embarrassed to ask this having been a Linux user for over 10 years - but I've never really dug deep into shell scripting.

One of the log rotate scripts on a small gateway contains this:

Code:
prerotate
     test ! -x /usr/sbin/sarg-reports || /usr/sbin/sarg-reports
endscript
postrotate
     test ! -e /var/run/squid.pid || /usr/sbin/squid -k rotate
endscript
Is my understanding flawed?

I'm assuming that if the prerotate line returns true that the postrotate section will run. If not the 'endscript' will terminate it?

I'm assuming the truth of prerotate is negated with ! and what that line basically says is if /usr/sbin/sarg-reports is not executable ... then I struggle to get the logical || or with just the file name.

If I could understand the purpose of the || or, I think I'd 'get it' and the postrotate line.

Be gentle with me, I'm ashamed enough that I don't know. Google has been little help to me (|| seems to upset it)
 
Old 03-03-2012, 04:56 AM   #2
firstfire
Member
 
Registered: Mar 2006
Location: Ekaterinburg, Russia
Distribution: Debian, Ubuntu
Posts: 706

Rep: Reputation: 426Reputation: 426Reputation: 426Reputation: 426Reputation: 426
Hi.

Command
Code:
test ! -x /usr/sbin/sarg-reports || /usr/sbin/sarg-reports
checks if /usr/sbin/sargs-reports is executable by you and, if so, executes it.

Quote:
Originally Posted by `man bash'
An OR list has the form

command1 || command2

command2 is executed if and only if command1 returns a non-zero exit status. The return status of AND
and OR lists is the exit status of the last command executed in the list.
Exit status of
Code:
test ! -x file
is 1 if `file' is executable by you.

Last edited by firstfire; 03-03-2012 at 05:00 AM.
 
1 members found this post helpful.
Old 03-03-2012, 04:57 AM   #3
cin_
Member
 
Registered: Dec 2010
Posts: 277

Rep: Reputation: 24
bash ||

Google likes ` bash || `.

It is an OR operator.

Last edited by cin_; 03-03-2012 at 04:58 AM. Reason: gramm`err
 
Old 03-03-2012, 05:01 AM   #4
Dark_Helmet
Senior Member
 
Registered: Jan 2003
Posts: 2,786

Rep: Reputation: 373Reputation: 373Reputation: 373Reputation: 373
What you're seeing is the original developer taking advantage of "short circuit" boolean evaluation.

You have two basic boolean operations where this comes into play: logical AND (&&) and logical OR (||).

If you have a statement such as "alpha && beta" then alpha must evaluate to true and beta must evaluate to true for the whole expression to evaluate to true. The point is that for logical AND, both alpha and beta must be evaluated to determine the overall expression.

Compare that with a statement such as "alpha || beta." There are three cases where the overall statement evaluates to true: (1) alpha = true; beta = false, (2) alpha = true; beta = true, (3) alpha = false; beta = true. Notice that if alpha evaluates to true, then it does not matter what beta evaluates to--the overall expression will still be true.

That's "short circuit" evaluation. The shell will evaluate only so much of the expression as is necessary to determine the overall result.

So, back to your code snippets, because they use ||, the second half of the statement will be ignored if the first half is true. Only when the first half evaluates to false will the second half get evaluated (which in this case is launching a new process).

EDIT:
It seems I was fashionably late to the party

Last edited by Dark_Helmet; 03-03-2012 at 05:04 AM.
 
1 members found this post helpful.
Old 03-03-2012, 05:03 AM   #5
leslie_jones
Member
 
Registered: Sep 2011
Posts: 130

Original Poster
Rep: Reputation: Disabled
Thank you. Much appreciated. Man Bash. Dear oh dear. How did I miss that.....
{head held in shame}
 
Old 03-03-2012, 05:13 AM   #6
leslie_jones
Member
 
Registered: Sep 2011
Posts: 130

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by Dark_Helmet View Post
So, back to your code snippets, because they use ||, the second half of the statement will be ignored if the first half is true. Only when the first half evaluates to false will the second half get evaluated (which in this case is launching a new process).
So let me see if I've got this clear when the left hand side of the or is false (that is I can't execute it).
Code:
test ! -x /usr/sbin/sarg-reports || /usr/sbin/sarg-reports
The right hand side would evaluate, but because I have no permissions to execute I presume it would dump an error to stderr. So in effect it does nothing. However, I'm guessing the exit code won't be zero meaning that 'endscript' will fire and postrotate won't ever run. Does that sound like I've got it? I think I'll have a play and see - just to be clear.

Quote:
Originally Posted by Dark_Helmet View Post
EDIT:
It seems I was fashionably late to the party
Hell, how can you be late? the DJ hasn't even turned up yet!

Sincere thanks to all. Kicking myself.
 
Old 03-03-2012, 05:21 AM   #7
Dark_Helmet
Senior Member
 
Registered: Jan 2003
Posts: 2,786

Rep: Reputation: 373Reputation: 373Reputation: 373Reputation: 373
And this is the cue for the entrance of the double-negative that is Unix process exit codes.

firstfire correctly stated that:
Code:
test ! -x file
returns 1 if you have execute permissions.

What you have to remember is, for Unix process exit codes, 0 is "success" or "true." A non-zero value is "failure" or "false."

That's the exact opposite of programming languages like C.

So, just to step through:

assuming you have execute privileges on the file
Code:
test -x file
will return 0 (i.e. "true")

Code:
test ! -x file
will return 1 (i.e. "false")

Because the left half evaluates to "false," the right half is evaluated--and hence, spawns the process.

EDIT:
And as for my being late, I must be, because firstfire and cin_ were already on the dance floor

Last edited by Dark_Helmet; 03-03-2012 at 05:26 AM.
 
Old 03-03-2012, 05:26 AM   #8
firstfire
Member
 
Registered: Mar 2006
Location: Ekaterinburg, Russia
Distribution: Debian, Ubuntu
Posts: 706

Rep: Reputation: 426Reputation: 426Reputation: 426Reputation: 426Reputation: 426
Equivalent command using AND (&&) operator would be
Code:
test -x /usr/sbin/sarg-reports && /usr/sbin/sarg-reports
To play with the logic, try something like
Code:
$ test  -x `which bash` && echo yes || echo no
yes

Last edited by firstfire; 03-03-2012 at 05:45 AM.
 
Old 03-03-2012, 06:16 AM   #9
cin_
Member
 
Registered: Dec 2010
Posts: 277

Rep: Reputation: 24
as led Isadora Duncan's, My Life

Quote:
If my virtue be a dancer's virtue, and if I have often sprung with both feet into golden-emerald rapture, and if it be my Alpha and Omega that every thing heavy shall become light, every body a dancer and every spirit a bird: verily, that is my Alpha and Omega.
Nietzsche, Thus Spoke Zarathustra

Last edited by cin_; 03-03-2012 at 06:19 AM. Reason: gramm`err
 
Old 03-03-2012, 07:06 AM   #10
leslie_jones
Member
 
Registered: Sep 2011
Posts: 130

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by Dark_Helmet View Post
And this is the cue for the entrance of the double-negative that is Unix process exit codes.
.....
What you have to remember is, for Unix process exit codes, 0 is "success" or "true." A non-zero value is "failure" or "false."

That's the exact opposite of programming languages like C.
That clears something up for me as I tend to think in C true 1 /false 0 in my head. But I'm really confused now! I figured 'experiment will solve this for me', but hell no! Let me step through, perhaps someone will spot my logic flaw and bomb.

I created a simple 'hello world' shell script and did NOT add execute to it. Testing with the example firstfire gave (modified) it seems to be the exact opposite of what I would expect.

Code:
$ test -x `/home/leslie/scripts/hello.sh` && echo yes || echo no
-bash: /home/leslie/scripts/hello.sh: Permission denied
yes
I don't have execute permissions and I read this evaluation using true = 0 and false =1 for shell, AND, I'm guessing that the exit code of 'echo yes' would be true/0. This may be a fatal flaw, but I'd expect an echo to complete with a return code of zero (true in shell).

If I don't have execute permissions test -x the result should be 1/false in shell speak. The other side of the AND is echo yes and fires because the return code 1 (a double bluff here) is logically 'true' and evaluation of the && clause continues - firing the echo. However, as I see it the shell would return '0' (true) for the echo statement, meaning the && as a whole should fail??? 1&&0 is not true???? Therefore the whole clause fails and the || or should be evaluated printing the 'no' to the screen - but this does not happen?

Clearly I'm wrong as 'no' never prints. If I invert the test
Code:
$ test ! -x `/home/leslie/scripts/hello.sh` && echo yes || echo no
-bash: /home/leslie/scripts/hello.sh: Permission denied
no
Am I right to be confused here?? I know that outside of logical malarky:

Code:
#!/bin/sh
if [ -x /home/leslie/scripts/hello.sh ]
then
    echo "is executable"
else
    echo "is not executable"
fi
Works as any sane rookie would expect it to work.

Somewhere, something in my brain is broken, can you help me fix it!

Quote:
Originally Posted by Dark_Helmet View Post
EDIT:
And as for my being late, I must be, because firstfire and cin_ were already on the dance floor
Magic, I can't trump that :-) Only to say for a good conga you need lots of people!
 
Old 03-03-2012, 07:17 AM   #11
leslie_jones
Member
 
Registered: Sep 2011
Posts: 130

Original Poster
Rep: Reputation: Disabled
Hang on! I'm being a divvy....

Quote:
If I don't have execute permissions test -x the result should be 1/false in shell speak. The other side of the AND is echo yes and fires because the return code 1 (a double bluff here) is logically 'true' and evaluation of the && clause continues - firing the echo. However, as I see it the shell would return '0' (true) for the echo statement, meaning the && as a whole should fail??? 1&&0 is not true???? Therefore the whole clause fails and the || or should be evaluated printing the 'no' to the screen - but this does not happen?
Of course it wont. 1&&0 is not true, sure. But the exit code will be a big fat 1 for shell (it's false) not a zero (this is not C). Hence the or IS satisfied.

Funny what a cup of tea will do!

Thanks to all. Finally....... derrrrrrrr.
 
Old 03-03-2012, 07:27 AM   #12
catkin
LQ 5k Club
 
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Debian
Posts: 8,576
Blog Entries: 31

Rep: Reputation: 1195Reputation: 1195Reputation: 1195Reputation: 1195Reputation: 1195Reputation: 1195Reputation: 1195Reputation: 1195Reputation: 1195
Quote:
Originally Posted by Dark_Helmet View Post
If you have a statement such as "alpha && beta" then alpha must evaluate to true and beta must evaluate to true for the whole expression to evaluate to true. The point is that for logical AND, both alpha and beta must be evaluated to determine the overall expression.
Only if alpha is true. From http://www.gnu.org/software/bash/man...nal-Constructs: "The && and || operators do not evaluate expression2 if the value of expression1 is sufficient to determine the return value of the entire conditional expression".
 
Old 03-03-2012, 07:35 AM   #13
catkin
LQ 5k Club
 
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Debian
Posts: 8,576
Blog Entries: 31

Rep: Reputation: 1195Reputation: 1195Reputation: 1195Reputation: 1195Reputation: 1195Reputation: 1195Reputation: 1195Reputation: 1195Reputation: 1195
Quote:
Originally Posted by leslie_jones View Post
Code:
prerotate
     test ! -x /usr/sbin/sarg-reports || /usr/sbin/sarg-reports
endscript
postrotate
     test ! -e /var/run/squid.pid || /usr/sbin/squid -k rotate
endscript
AFAIK, under bash test ! -x /usr/sbin/sarg-reports || /usr/sbin/sarg-reports is functionally identical to the more natural test -x /usr/sbin/sarg-reports && /usr/sbin/sarg-reports.

I cannot think why the programmer chose the more convoluted form.
 
Old 03-03-2012, 12:44 PM   #14
Dark_Helmet
Senior Member
 
Registered: Jan 2003
Posts: 2,786

Rep: Reputation: 373Reputation: 373Reputation: 373Reputation: 373
Quote:
Originally Posted by catkin
Only if alpha is true.
I just KNEW somebody was going to call me on that!

Yes, my original description was incomplete.

If the first/left half of a logical AND evaluates to false, the second/right half will not be evaluated--because there is no value for that portion which could make the entire statement evaluate to true.

Sorry to anyone if my haphazard response caused confusion.

And I gotta say, this is turning out to be a decent conga line.
 
  


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
[SOLVED] Silencing the line "echo test > test/test.txt" in a shell script Arenlor Linux - General 2 06-18-2010 02:37 PM
How to test is a drive is mounted in a shell script? agtlewis Linux - General 7 03-18-2009 10:58 AM
Shell script --test r/o file system. knockout_artist Linux - Newbie 2 11-06-2007 11:39 AM
how to test if user is root or not in a shell script? dr_zayus69 Programming 3 08-17-2005 04:00 AM
Shell script to test my shell alltime Programming 5 04-22-2005 08:24 PM

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

All times are GMT -5. The time now is 12:26 AM.

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