LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
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 03-20-2010, 06:10 PM   #1
Cotun
Member
 
Registered: Jan 2009
Location: UK
Distribution: Debian Stable and Unstable
Posts: 61

Rep: Reputation: 21
Rc.Local Errorlevel Exits Script


Hi everybody

I've got an unusual problem with a segment of script in my Linux rc.local file, which is automatically executed when the system starts up.

The code is shown below:

---- Start ----

echo -n "Testing current SMART status..."
echo
SMARTOUT=`smartctl -H /dev/sda -d ata | grep "SMART overall-health self-assessment test result: PASSED"`
echo
if [ -z "$SMARTOUT" ]
then
echo
echo
echo Smart Test Failed!!!
echo
echo -n "Press Enter to continue to boot: "
read dummy
echo
else
echo "done"
fi

---- End ----

The code itself is fine and runs properly. However, when used in the /etc/rc.local file, it only executes correctly when the string I search for is found. Any other scenarios results in the script exiting at the SMARTOUT=`... line. I found this problem by accident when installing the script on another machine with a different hard disk configuration. This was somewhat fortunate, as any SMART error would not have shown up.

I suspect in cases where the string is not found that grep is outputting an error level other than 0, which is causing the rc.local script to abandon immediately. I haven't been able to determine if you can suppress grep's errorlevel output, it seems not from what I can tell. I also tried to use Bash's string management features, but without grep, the output becomes multi-line and I had all kinds of trouble with it. At the moment, I'm kinda stumped.

Does anybody know how I could achieve the same results without running into these issue?

Thanks

Cotun
 
Old 03-20-2010, 06:19 PM   #2
GrapefruiTgirl
LQ Guru
 
Registered: Dec 2006
Location: underground
Distribution: Slackware64
Posts: 7,594

Rep: Reputation: 556Reputation: 556Reputation: 556Reputation: 556Reputation: 556Reputation: 556
I believe you'll find that the problem goes away if you put the shell-subfunction in quotes, like so:

Code:
SMARTOUT="`smartctl -H /dev/sda -d ata | \
grep "SMART overall-health self-assessment test result: PASSED"`"
This way, even if the command returns nothing, it is still a string, albeit an empty one. Without quotes, it may be coming back as an integer, possibly from grep.

Not sure what you mean by "suppress grep's errorlevel output", but if you want to make grep be quiet, I believe there's a -q option (check the man page) and also, you could simply dump stderr into the trash, like:

Code:
SMARTOUT="`smartctl -H /dev/sda -d ata | \
grep "SMART overall-health self-assessment test result: PASSED" 2>/dev/null `"
and that should shut up any visible erorr messages from grep.

Hope that gets you somewhere

Sasha

Oh, P.S. Please use code tags: http://www.phpbb.com/community/faq.php?mode=bbcode#f2r1

EDIT: Or, use `grep -c` which will count how many times the string was found, and return that number as an integer, thereby eliminating the need for strings entirely.

Last edited by GrapefruiTgirl; 03-20-2010 at 06:30 PM. Reason: Broke the lines at \ to make more readable.
 
1 members found this post helpful.
Old 03-27-2010, 04:17 PM   #3
Cotun
Member
 
Registered: Jan 2009
Location: UK
Distribution: Debian Stable and Unstable
Posts: 61

Original Poster
Rep: Reputation: 21
Thanks for your reply, my apology for the very late response, I wasn't at home I'll use the code tags as you suggested.

All three of your solutions as well as the original approach work correctly in Bash. Unfortunately none of them had any effect on the problem. However, all three of your solutions relate to what is output to the SMARTOUT variable. However, given the script actually terminates without warning or error at this very line, I had to assume that what is output to SMARTOUT is actually not the issue at all and something else terminates the script. I could only assume that it was the grep non-zero errorlevel output, but I couldn't see why this would exit the script as it did.

Quote:
The code itself is fine and runs properly. However, when used in the /etc/rc.local file
However, I managed to determine the reason for this after reading the above line from my original statement. The code runs fine on the default interpreter, i.e Bash. But the rc.local file calls "/bin/sh -e" as the interpreter. I removed the -e parameter assuming it might relate to exiting at an errorlevel other than 0 and sure enough that fixes the problem. However, I'm not really keen to remove that parameter on the /etc/rc.local file as it shields against script errors.

Anybody have any ideas how I can achieve what I need without removing that parameter?

Thanks again
 
Old 03-27-2010, 06:27 PM   #4
GrapefruiTgirl
LQ Guru
 
Registered: Dec 2006
Location: underground
Distribution: Slackware64
Posts: 7,594

Rep: Reputation: 556Reputation: 556Reputation: 556Reputation: 556Reputation: 556Reputation: 556
Quote:
I removed the -e parameter assuming it might relate to exiting at an errorlevel other than 0 and sure enough that fixes the problem. However, I'm not really keen to remove that parameter on the /etc/rc.local file as it shields against script errors.
Hmm.. Maybe you should be looking at this in a different way. Specifically: it is evident that using the -e option to the interpreter is NOT in fact "shielding you" against any errors, but the opposite: it's making your script exit for no obvious reason.

On my own system at least, on each version of my OS that I've used over a few years, init scripts do not use the -e option to the interpreter (and if you really wanted, you can set/unset -e as you wish in different locations).

Instead, it is probably a better idea to do some proper sanity checking and logging during the execution of the script itself; this way, if something goes awry during execution, you at least have a nice record of what it was doing when it terminated unexpectedly. This logging might include outputting a message to stderr when something returns with a non-zero status.

Also, you might be able to customize how -e performs, though I'm not sure about this; try `help set` in bash, for some options for setting things like -e

Sasha
 
1 members found this post helpful.
Old 03-27-2010, 06:30 PM   #5
GazL
LQ Veteran
 
Registered: May 2008
Posts: 6,897

Rep: Reputation: 5018Reputation: 5018Reputation: 5018Reputation: 5018Reputation: 5018Reputation: 5018Reputation: 5018Reputation: 5018Reputation: 5018Reputation: 5018Reputation: 5018
grep will exit with rc 1 if it doesn't match the string, which will trigger the -e trap.

If you need $SMARTOUT to refer to later in your script, then doing the following will avoid tripping the set -e trap.

Code:
SMARTOUT=`smartctl -H /dev/sda -d ata | grep "SMART overall-health self-assessment test result: PASSED"||true`
If you don't need to refer to $SMARTOUT again, I'd go for something like the following instead.

Code:
if smartctl -H /dev/sda -d ata | grep "SMART overall-health self-assessment test result: PASSED"
  then
     # do stuff when it passes
  else
     # do stuff when it fails
fi
add -q to the grep if you don't want to see the output of the smartctl line on stdout.


I agree with Grapefruitgirl's approach though. set -e is a blunt instrument and it's much better IMO to catch your own errors and take appropriate action.

Last edited by GazL; 03-27-2010 at 06:33 PM.
 
1 members found this post helpful.
Old 03-28-2010, 12:54 PM   #6
Cotun
Member
 
Registered: Jan 2009
Location: UK
Distribution: Debian Stable and Unstable
Posts: 61

Original Poster
Rep: Reputation: 21
Hey all

Quote:
Hmm.. Maybe you should be looking at this in a different way. Specifically: it is evident that using the -e option to the interpreter is NOT in fact "shielding you" against any errors, but the opposite: it's making your script exit for no obvious reason.
I have to firstly point out that it's not my script, but the one provided by Debian by default I merely edited it to add things I need. However, I just checked and there's nothing else in there not written by me so it's a moot point.

I agree with your thoughts though. I never use the -e parameter or even the sh interpreter for any of my personal scripts. I'll take the approach you suggested and alter my /etc/rc.local file appropriately.

Thanks to both of you for your suggestions

Cotun
 
  


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
Shell script exits after running a chroot command kechlion Linux - Newbie 4 01-04-2010 09:28 AM
bash - setting a persistent variable that remains after the script exits CJ Chitwood Programming 9 01-24-2009 07:48 PM
Log what exits in bash script. What causes exit code thats not 0? Trailsmoke Programming 2 09-25-2008 03:07 AM
script exits tostay2003 Programming 4 12-26-2007 08:13 AM
Flagging exits in Bash Script dtheorem Programming 5 11-08-2003 10:15 PM

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

All times are GMT -5. The time now is 11:07 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