LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   trap error and assign in bash script (https://www.linuxquestions.org/questions/linux-newbie-8/trap-error-and-assign-in-bash-script-4175539607/)

vrusu 04-13-2015 02:04 PM

trap error and assign in bash script
 
hi
I try to assign return from a _error_handler_function to a variable
this is just a test( dummy test ) not a really case


#!/bin/bash
logfile="/dev/shm/log.err"
exec 2>$logfile
_err_handler(){
v=$(cat $logfile|grep dummy|wc -l);
rm $logfile
echo $v
}

trap _err_handler ERR

x=$(dummy);
echo "x value is $x "
z=$(notrap)
echo "z value is $z"


expected output :
bash-4.1$ sh test2.sh
x value is 1
z value is 0


what is wrong here and how should I fix?

thanks in advance

joe_2000 04-13-2015 03:02 PM

Interesting problem. I have never used trap (although it has been on my todo list for a while) so I can't give you a fix, but I think I can see what goes wrong.

When you call dummy the error handler is invoked, but you are not in the context of the invoking call anymore, so the variable assignment never happens.
If you add
Code:

x=$v
to the end of the error handlers function body you get
Code:

user@localhost:~$ ./test.sh
1
x value is 1
0
z value is

Onviously not a fix, but it gives a pointer as to how the code behaves. I'll play a bit with this further...

joe_2000 04-13-2015 03:58 PM

How is this
Code:

#!/bin/bash
logfile="/tmp/log.err"
exec 2>$logfile
_err_handler(){
    v=$(cat $logfile|grep dummy|wc -l);
    rm $logfile
    LAST_V=$v
}

trap _err_handler ERR

dummy
x=$LAST_V
echo "x value is $x "
notrap
z=$LAST_V
echo "z value is $z"


grail 04-13-2015 09:15 PM

So here is another alternative. Basically I do not like passing around global variables if I can help it. Also, I wasn't sure if we should be completely removing the logfile or just truncating?
My thought here was that you want the code to keep running but by removing it you have broken the link to the file and left a dangling exec with no closure.

So here is what I have:
Code:

logfile="/tmp/log.err"
exec 2>$logfile

_err_handler(){
  local last_command
  local var

  last_command=$BASH_COMMAND

  if [[ "$last_command" =~ = ]]
  then
    var=${last_command%=*}
    read -r ${var} <<< $(cat $logfile|grep dummy|wc -l)
  fi
  :> $logfile
}

trap _err_handler ERR

x=$(dummy)
echo "x value is $x "

z=$(notrap)
echo "z value is $z"

Now you may wish to play with the regex but essentially it is just looking to see if the last command had an equals in it and so assigns back to whatever variable was being used.

vrusu 04-13-2015 10:35 PM

thank you both!!

i'm wondering if there is a way to change _error_handler to also allow use directly in test condition:

[[ 0 -lt $(dummy) ]] && echo "is a dummy (test)"

instead of assignment and test
x=$(dummy);
[[ 0 -lt $x ]] && echo " has a dummy"

grail 04-13-2015 10:53 PM

I am not sure I follow? Why not just test $? after the assignment and if errored (> 0) then do what you need?

Overall it may help if you explained what you actually need as grepping the error in a file when you know it will happen seems a little pointless.

joe_2000 04-14-2015 12:06 PM

Quote:

Originally Posted by grail (Post 5347008)
So here is another alternative. Basically I do not like passing around global variables if I can help it. Also, I wasn't sure if we should be completely removing the logfile or just truncating?
My thought here was that you want the code to keep running but by removing it you have broken the link to the file and left a dangling exec with no closure.

So here is what I have:
Code:

logfile="/tmp/log.err"
exec 2>$logfile

_err_handler(){
  local last_command
  local var
variable assign
  last_command=$BASH_COMMAND

  if [[ "$last_command" =~ = ]]
  then
    var=${last_command%=*}
    read -r ${var} <<< $(cat $logfile|grep dummy|wc -l)
  fi
  :> $logfile
}

trap _err_handler ERR

x=$(dummy)
echo "x value is $x "

z=$(notrap)
echo "z value is $z"

Now you may wish to play with the regex but essentially it is just looking to see if the last command had an equals in it and so assigns back to whatever variable was being used.

I learned something today. Didn't no either $BASH_COMMAND nor the trick to use read to do the variable assignment.

That said, I'll allow myself to point out that your code still ends up using global variables.

grail 04-15-2015 12:20 AM

Quote:

That said, I'll allow myself to point out that your code still ends up using global variables.
True in this case :) I pulled this from an old remnant of code I had where I was passing the variables in, but the beauty here is that you do not have to define what those variables are in the function :)

joe_2000 04-15-2015 07:58 AM

Quote:

Originally Posted by grail (Post 5347574)
True in this case :) I pulled this from an old remnant of code I had where I was passing the variables in, but the beauty here is that you do not have to define what those variables are in the function :)

Agreed


All times are GMT -5. The time now is 03:35 AM.