LinuxQuestions.org
Visit Jeremy's Blog.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 12-13-2012, 06:14 AM   #1
Michal Krzyz
Member
 
Registered: Nov 2011
Distribution: OpenBSD, Ubuntu, Debian, Slackware, LFS
Posts: 44

Rep: Reputation: Disabled
Problem with Bash error handling. Smart solution is needed.


I have a question regarding error handling in BASH. I was using following code to handle errors:

Code:
#!/bin/bash
set -e
...
# a lot of lines
...
and my script stopped somwhere on the line:

Code:
PARTITION_DEV=/dev/sdb1
...
PARTITION_RECORD="$(mount | grep $PARTITION_DEV)"   # HERE PROBLEM OCCURED
...
Error code was returned by grep (which means that partition is not mounted), but I did not want to stop execution here (I will test PARTITION_RECORD for zero len string).
...so I did workaround solution for this line:

Code:
PARTITION_DEV=/dev/sdb1
...
set +e
PARTITION_RECORD=$(mount | grep $PARTITION_DEV)
set -e
...
then problem seems to be fixed. Thing is that I wanted to add custom error message (in current solution script stops on error, and sometimes do not display anything). So I added following code to my script:

Code:
# !/bin/bash
set -e

function error_exit()
{
  echo "Error: File: $0 Line: $1"
  exit 1
}
trace 'error_exit ${LINENO}' ERR
...
PARTITION_DEV=/dev/sdb1
...
set +e
PARTITION_RECORD=$(mount | grep $PARTITION_DEV)
set -e
...
But this is not working at all. Program is stopped on the pipe, and display information by custom error function.
Do you know how to solve this problem? Is there any smart solution for bash error handling with custom messages?
 
Old 12-13-2012, 08:07 AM   #2
bijo505
Member
 
Registered: Nov 2012
Location: Bangalore
Distribution: Fedora & Ubuntu
Posts: 77

Rep: Reputation: 18
Hi,
Can you try with bash -bvx <script name>? So it will run in verbose mode and will get to know, what is happening while executing.

-b Notify of job termination immediately.
-v Print shell input lines as they are read.
-x Print commands and their arguments as they are executed.

--
Thanks,
Bijo
 
Old 12-13-2012, 08:18 AM   #3
Michal Krzyz
Member
 
Registered: Nov 2011
Distribution: OpenBSD, Ubuntu, Debian, Slackware, LFS
Posts: 44

Original Poster
Rep: Reputation: Disabled
I know exactly what happened, grep returned error because he did not match the pattern. I would like to know how to make it work (how to make grep quiet).
I am trying combination of set -e and trap 'exit' EXIT (instead of trap 'error_exit' ERR) but exit 0 command gives ERROR_CODE = 1 in my exit trap ! I do not know why (bash seems to be bugged in this question).
 
Old 12-13-2012, 08:34 AM   #4
Michal Krzyz
Member
 
Registered: Nov 2011
Distribution: OpenBSD, Ubuntu, Debian, Slackware, LFS
Posts: 44

Original Poster
Rep: Reputation: Disabled
I found one solution, but please do not tell me that my problem can not be solved in another way.

My problematic grep line now looks as follows:

Code:
...
# no set +e command here
PARTITION_RECORD=$(mount | grep $PARTITION_DEV || echo "")
# no set -e command here
...
...and it is working.

I have nothing against set +e, set -e solution (nothing but it is not working at all ).
On the other hand presented solution seems to make my code more complex and it is harder to read it...
if this is truly only one solution of my problem, then I will be thinking about moving my stuff to another shell :/ (maybe it could be better to spent my effort learning tcsh than bugfixing/workarrounding bash shell).
 
Old 12-13-2012, 09:50 AM   #5
unSpawn
Moderator
 
Registered: May 2001
Posts: 29,331
Blog Entries: 55

Rep: Reputation: 3530Reputation: 3530Reputation: 3530Reputation: 3530Reputation: 3530Reputation: 3530Reputation: 3530Reputation: 3530Reputation: 3530Reputation: 3530Reputation: 3530
Code:
# No need to call mount
STRING=(grep -m1 "^${PARTITION_DEV}" /proc/mounts 2>/dev/null)
# If len of string not zero then it must contain something
[ ${STRING} -ne 0 ] && PARTITION_RECORD="${STRING}"
 
Old 12-13-2012, 12:06 PM   #6
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Arch
Posts: 3,013

Rep: Reputation: 1225Reputation: 1225Reputation: 1225Reputation: 1225Reputation: 1225Reputation: 1225Reputation: 1225Reputation: 1225Reputation: 1225
Quote:
Originally Posted by Michal Krzyz View Post
Thing is that I wanted to add custom error message (in current solution script stops on error, and sometimes do not display anything). So I added following code to my script:

Code:
...
trace 'error_exit ${LINENO}' ERR
...
Did you mean trap instead of trace there?

Assuming you meant trap, set -e has no effect on this:
Quote:
trap [-lp] [arg] [sigspec Ö]

If a sigspec is ERR, the command arg is executed whenever a simple command has a non-zero exit status, subject to the following conditions. The ERR trap is not executed if the failed command is part of the command list immediately following an until or while keyword, part of the test following the if or elif reserved words, part of a command executed in a && or || list, or if the commandís return status is being inverted using !. These are the same conditions obeyed by the errexit option.
You could also pass through cat to hide the error code: $(grep ... | cat)

Quote:
if this is truly only one solution of my problem, then I will be thinking about moving my stuff to another shell :/ (maybe it could be better to spent my effort learning tcsh than bugfixing/workarrounding bash shell).
I would suggest not using a shell at all; shells make tradeoffs in favour of interactive use at the expense of writing programs.
 
Old 12-14-2012, 03:35 AM   #7
Michal Krzyz
Member
 
Registered: Nov 2011
Distribution: OpenBSD, Ubuntu, Debian, Slackware, LFS
Posts: 44

Original Poster
Rep: Reputation: Disabled
Thank you for your answer.
Of course there should be 'trap' instead of 'trace'.

I like $(grep ... | cat) solution, it is more readable than || echo "" (but still looks strange for me)

Quote:
...
I would suggest not using a shell at all; shells make tradeoffs in favour of interactive use at the expense of writing program
I had to choose something between bash scripting or make. I chosen bash scripts because in near feature I will add progression checking code and it will be easier to do it in bash (the code which will be responsible for skipping part of installation script which was done before...it could be useful when script will crash and I will call it again after fix).
So how should I write my installator?
 
Old 12-14-2012, 12:09 PM   #8
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Arch
Posts: 3,013

Rep: Reputation: 1225Reputation: 1225Reputation: 1225Reputation: 1225Reputation: 1225Reputation: 1225Reputation: 1225Reputation: 1225Reputation: 1225
Quote:
Originally Posted by Michal Krzyz View Post
I like $(grep ... | cat) solution, it is more readable than || echo "" (but still looks strange for me)
Another possibility would be to use a global variable to tell your ERR handler not to do anything:
Code:
# !/bin/bash

function error_exit()
{
  echo "Error: File: $0 Line: $1"
  exit 1
}
trap '[ "$IGNORE_ERROR" = YES ] || error_exit ${LINENO}' ERR
...
IGNORE_ERROR=YES
PARTITION_RECORD=$(mount | grep $PARTITION_DEV)
IGNORE_ERROR=NO
...

Quote:
I had to choose something between bash scripting or make. ...
So how should I write my installator?
The traditional choice for that sort thing is perl, I guess python is more fashionable now. Either one would be better than bash or make.
 
1 members found this post helpful.
Old 12-14-2012, 02:12 PM   #9
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 9,254

Rep: Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686
Obviously it is just me, but I would like to ask a question from the original post.

You mentioned that the following code:
Code:
PARTITION_RECORD="$(mount | grep $PARTITION_DEV)"
Has the following result:
Quote:
Error code was returned by grep (which means that partition is not mounted)
My question is ... what error?? Grep will not return an error on something not being there, it will simply return an empty string.

I am well curious if you would display the error message received
 
Old 12-14-2012, 02:46 PM   #10
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Arch
Posts: 3,013

Rep: Reputation: 1225Reputation: 1225Reputation: 1225Reputation: 1225Reputation: 1225Reputation: 1225Reputation: 1225Reputation: 1225Reputation: 1225
Quote:
Originally Posted by grail View Post
My question is ... what error?? Grep will not return an error on something not being there, it will simply return an empty string.
It will have a non-zero exit status, which is interpreted as an error for the purposes of the ERR trap (see post #6).
 
Old 12-14-2012, 03:11 PM   #11
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 9,254

Rep: Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686
Yes that would make sense once the trap is in place, but according the OP, the option to trap was placed in later to avert this error / issue. In the OP it is listed that grep
returns an error on that line of code. My point is that I can see no reason it would and cannot reproduce such an error.
 
Old 12-14-2012, 04:26 PM   #12
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Arch
Posts: 3,013

Rep: Reputation: 1225Reputation: 1225Reputation: 1225Reputation: 1225Reputation: 1225Reputation: 1225Reputation: 1225Reputation: 1225Reputation: 1225
Quote:
Originally Posted by grail View Post
according the OP, the option to trap was placed in later to avert this error / issue.
No, set -e was initially used, and set +e ... grep ... set -e was used to avoid exiting on failed grep. Then the trap was placed to get a custom error message. However, the OP didn't realize that the trap is triggered completely independantly of set -/+e, thus the question.
 
Old 12-15-2012, 05:32 AM   #13
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 9,254

Rep: Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686
Again, this option was selected after, but I am guessing you are correct that he had an option set that he did not advise of prior to the other options being set.
 
Old 12-15-2012, 06:18 AM   #14
jlinkels
Senior Member
 
Registered: Oct 2003
Location: Bonaire
Distribution: Debian Wheezy/Jessie/Sid, Linux Mint DE
Posts: 4,493

Rep: Reputation: 635Reputation: 635Reputation: 635Reputation: 635Reputation: 635Reputation: 635
Checking whether a disk is mounted or not is easy. I use this for years. Proper error reporting, no premature termination.
Code:
df -h | grep $mount_point > /dev/null
if [ $? -eq 0 ]
        echo "mount point $mount_point exists
else
        echo "Error: mount point $mount_point does not existskipped"
fi
jlinkels
 
Old 12-15-2012, 07:02 AM   #15
Michal Krzyz
Member
 
Registered: Nov 2011
Distribution: OpenBSD, Ubuntu, Debian, Slackware, LFS
Posts: 44

Original Poster
Rep: Reputation: Disabled
I think that you are not using trap '...' ERR
even your df | grep command will not work in this case, because grep will return error code (number different than 0!) when expression will not be matched and then you will be informed that ERR condition occured.
I chosen solution with ... | cat it seems to be strange but anyway who thinks that bash is not strange? Probably only people who do not know bash.

Similar workarround which I had to use was something like (actually I had to use more similar workarrounds):

Code:
$ sudo echo "TERM=xterm" >> /root/.bashrc    # of course it is too simple to work in bash :)

# so I had to do it in following way:

$ sudo echo "TERM=xterm" | sudo tee -a /root/.bashrc > /dev/null
REALLY? ISN'T BASH AMAZING? <sarcasm>
 
  


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
try/except error handling in bash desromic Programming 4 06-30-2011 04:04 PM
[SOLVED] bash error handling m3phisto Linux - Newbie 4 04-26-2011 08:28 AM
error 127 solution needed vvajeesh Linux - Newbie 4 03-02-2010 11:03 AM
Help needed for error handling in C montylee Programming 11 08-27-2008 11:44 PM
Bash Script and Loop error handling Kedelfor Programming 5 05-22-2005 03:22 PM


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