Solved What causes the premature end of a bash script?

Code:
freebsd-version
12.3-RELEASE-p5

I have a bash script with a function that contains the following code:

Code:
. . .

OPT_t=0
. . .

    t)
      let "OPT_t+=1"
      ;;
. . .

f_msg_attach()
{

  local _passed_msg_file _passed_attach_file _passed_content_type
  _passed_msg_file="$1"
  _passed_attach_file="$2"
  _passed_content_type="$3"

  [ "$OPT_t" -gt 1 ] && echo "Processing: $_passed_attach_file  Content-Type: ${_passed_content_type}"

  local _content_block _file_name

  _file_name="$(basename "${_passed_attach_file}")"

  # Second line indent indicates continuation from preceding line
 _content_block=$(cat << CBLK

--${MIME_MP_BOUNDARY}
Content-Type: ${_passed_content_type};
  name="${_file_name}"
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
  filename="${_file_name}"
CBLK
)

  echo "${_content_block}"                >>  "${_passed_msg_file}"
  echo -e ""                              >>  "${_passed_msg_file}"
  base64 -e "${_passed_attach_file}"      >>  "${_passed_msg_file}"

  [ "$OPT_t" -gt 1 ] &&  ls -l "${_passed_msg_file}"

}

When the script is run, with or without a -t option, the script halts at this line:
Code:
Line 235: echo -e ''
Line 236: base64 -e /usr/local/www/apache24/data/hll_DaV/upload/eBillings/IN356000-IN356999/IN356753/HLL_Employee_Timesheet.ots
Line 238: '[' 0 -gt 1 ']'

If the line is commented out then the script runs as expected. Note that the same idiom is used earlier in the function and the script does not fail at that point.

What is wrong with this code?

A. When OPT_t is 1 or less then the function returns false which stops the script. Adding a no-op or any other instruction that succeeds after the test prevents the problem arising when the test fails. So: [ "$OPT_t" -gt 1 ] && ls -l "${_passed_msg_file}" || :
 
Comment out which line?
Line 238?
Well look at it: "test is 0 greater than 1" that always fails so of course it should exit.
It looks like you are trying to count "how many -t options are passed" and if you don't call it with at least one -t it's going to fail.
I'm not convinced that the let "OPT_t+=1"is doing what you think it is.
 
The code says this: [ "$OPT_t" -gt 1 ] && ls -l "${_passed_msg_file}"

SO, as I understand it, if "$OPT_t" has a value of 1 or less then the code should drop to the next line. If "$OPT_t" is greater than 1 then the ls command is executed.

By experiment I discovered that adding a : null command following the conditional corrects the problem. As the original problem line was the very last line of a function I infer there is something odd about the behaviour when there is nothing following a failed test and the function returns.
 

SirDice

Administrator
Staff member
Administrator
Moderator
It looks like you are trying to count "how many -t options are passed" and if you don't call it with at least one -t it's going to fail.
There has to be at least two -t. The test is greater than 1. So 0 -t and 1 -t are going to fail.

use -ge 1 ?
Yeah, or -gt 0. But -ge 1 is probably better, it's clearer what's expected here; "There has to 1 or more -t options"
 
Have you set to error out on the script?

The function f_msg_attach result is non-zero if this last test for the t-option fails.

Put a return 0 at the end of the function.
 
By experiment I discovered that adding a : null command following the conditional corrects the problem. As the original problem line was the very last line of a function I infer there is something odd about the behaviour when there is nothing following a failed test and the function returns.
Without an explicit return statement, the value returned by f_msg_attach() will be the return status of the last command executed inside the function. A colon has exactly the same impact as /bin/true. So, I am guessing that the value returned by the function matters, and should probably be set explicitly. However, you have not provided us with enough context to examine that.

Edit: I see that arlecchino made a similar conclusion above.
 
Top