0

I have a COBOL program which should be run thru shell script and should accept the values from the here document. in the here document, i should call a function that should let control to be exit abnormally with exit code.

I have tried as below but it is not working for me.

This is my COBOL program:

   01  WW-ANS              PIC X value space. 

IRS-200.
      display "ARE THE ABOVE ANSWERS CORRECT? Y/N/E".
      Accept ws-ans.
      display "entered value is " ws-ans "<".

      IF WW-ANS  =  "E"  or "e"
         PERFORM STOP-RUN-CA.

      IF WW-ANS  NOT =  "Y" AND "N" AND "E"      
                    and "y" and "n" and "e"      
          PERFORM DISPLAY-01 THRU DISPLAY-01-EXIT
          GO  TO  IRS-200.

      IF WW-ANS  =  "Y" or "y"                   
          display "Program executed successfully"
          PERFORM STOP-RUN-CA. 
      ELSE                                       
          GO  TO  IRS-200.

DISPLAY-01.                       
      DISPLAY "value is >" WW-ANS "<".
      DISPLAY "INVALID RESPONSE".

This is my shell script:

#!/bin/bash
funexit ()
{
echo "calling funexit"
exit 1
}

/caplus/pub/test123<<:EOD:
1
g
$(funexit)
Y
:EOD:

Output is:

[Linux Dev:adminusr ~]$ ./test123.sh
ARE THE ABOVE ANSWERS CORRECT? Y/N/E
entered value is 1<
value is >1<
INVALID RESPONSE
ARE THE ABOVE ANSWERS CORRECT? Y/N/E
entered value is g<
value is >G<
INVALID RESPONSE
ARE THE ABOVE ANSWERS CORRECT? Y/N/E
entered value is  c<
value is >C<
INVALID RESPONSE
ARE THE ABOVE ANSWERS CORRECT? Y/N/E
entered value is Y<
Program executed successfully

When ever function gets called from here document the COBOL program accept the value as "C", since at function: it invoke the echo command and considering the first character from the "calling funexit" string, instead of getting exit.

From the function, I have removed echo statement like below:

#!/bin/bash
funexit ()
{
exit 1
}

/caplus/pub/test123<<:EOD:
1
g
$(funexit)
Y
:EOD:

Output is:

[Linux Dev:adminusr ~]$ ./test123.sh
ARE THE ABOVE ANSWERS CORRECT? Y/N/E
entered value is 1<
value is >1<
INVALID RESPONSE
ARE THE ABOVE ANSWERS CORRECT? Y/N/E
entered value is g<
value is >G<
INVALID RESPONSE
ARE THE ABOVE ANSWERS CORRECT? Y/N/E
entered value is   <
value is > <
INVALID RESPONSE
ARE THE ABOVE ANSWERS CORRECT? Y/N/E
entered value is Y<
Program executed successfully.

When ever function gets called from here document the COBOL program accept the value as spaces instead of getting exit.

The script should get exit abnormally with some exit code.

Cœur
  • 37,241
  • 25
  • 195
  • 267
ANR
  • 543
  • 1
  • 4
  • 13
  • If you used terminal instead of a heredoc, what would be the equivalent of "exit"? – choroba Feb 24 '14 at 12:48
  • @choroba.. If i understtod you correctly terminal means at command line. If so, At command line the exit will work. But my requirement is to call the COBOL program thru shell script by passing accept variables to it thru shell script.This can only be possbile with heredoc only. So i should use heredoc. there is not restriction to use exit statement. any shell control break statement/ logic may use to exit from the process abnormally.. – ANR Feb 24 '14 at 13:03

5 Answers5

1

This example looks contrived because you are giving it both static input. However, that is probably because this is just a simplified example.

I guess is that you want funexit to return the E so that the input would mean that there is no more input, and nothing if there is more input. To be clear, the funexit script is called (and finishes) before COBOL is called.

I think you would want to code your shell script like this:

#!/bin/bash
funexit ()
{
  echo calling funexit 1>&2
  echo E
}

/caplus/pub/test123<<:EOD:
1
g
$(funexit)Y
:EOD:

Notice that the call to funexit and the following Y are on the same line. That way, if funexit did not return anything, the cobol program would not see a blank line. If funexit returns an E (actually an E followed by a new line) it would see the E.

Also notice that your debugging output of "Calling funexit" is redirected to standard error; before it was being sent to the cobol program and it ACCEPTed the letter C (from "Calling").

And lastly, the funexit script does not need to exit, as that is what will happen at the end of the script anyway.

Scott Nelson
  • 568
  • 2
  • 17
1

@ANR;

Use ACCEPT ... ON EXCEPTION

Ala

   identification division.
   program-id. sample.

   data division.
   working-storage section.
   01 the-fields.
      05 field-one         pic x(8).
      05 field-two         pic x(8).
      05 field-three       pic x(8).
      05 field-four        pic x(8).

  *> ***************************************************************
   procedure division.

   accept field-one end-accept
   display field-one end-display

   accept field-two end-accept
   display field-two end-display

   accept field-three
       on exception
           display "no field three entered" end-display
       not on exception
          display field-three end-display
   end-accept

   accept field-four
       on exception
           display "no field four entered" end-display
       not on exception
           display field-four end-display
   end-accept

   goback.
   end program sample.

So a run with four lines of input looks like

./sample <fourdatums.txt
one
two
three
four

and with only three

./sample <threedatums.txt
one
two
three
no field four entered
Brian Tiffin
  • 3,978
  • 1
  • 24
  • 34
  • @Brain Tiffin.. My sinciealy thanks to you. But i dont want to chage the COBOL code. I should deal from the shell script only. when ever the improper set of input values passed from the shell script to COBOL, shell script should get exit with abnormal exit condition.. Could you please share if you have any thoughts about it. – ANR Feb 28 '14 at 07:15
  • @ANR; Sorry ANR, but data will never be able to influence code. Never, ever. Lack of data will never influence the console ACCEPT, the COBOL program will just continue running the code flow. If you are writing the shell scripts, and know that you aren't going to feed enough data, don't run the program and exit 1 instead. If you don't mind abrupt abends, send a `kill -9 ` after you feed a few data lines in the heredoc. Again, you will never be able to 'inject' an exit in a data stream to COBOL. But you can kill the process (outside the heredoc, not in). – Brian Tiffin Feb 28 '14 at 09:51
0

Since funexit is executed in a subshell created by the command substitution, you'll need to check its exit status outside the here document to determine if the parent shell should exit.

#!/bin/bash
funexit () {
  echo "calling funexit"
  exit 1
}

output=$(funexit) || exit

/caplus/pub/test123<<:EOD:
1
g
$output
Y
:EOD:
chepner
  • 497,756
  • 71
  • 530
  • 681
  • @chepner.. I tried your suggestion, but it does not work for my requirement. It getting exit from the script and does not allow me execute COBOL program. – ANR Feb 25 '14 at 16:22
  • Are you saying you want your COBOL program to exit when `funexit` is called? That's not possible. `funexit` is called before `test123` ever runs. If you want `funexit` to not be called until `test123 has already read the preceding lines of input, you're going to have to rewrite the program. – chepner Feb 25 '14 at 16:42
  • Thanks for quick responce @chepner.. Do you think is there any possible way about how to invoke COBOL program thru shell script.? – ANR Feb 25 '14 at 16:49
  • No; your Cobol code itself needs to call `funexit` at the appropriate time (or at least take as input whether `funexit` succeeded or failed when it was called), so that it can take the appropriate action. – chepner Feb 25 '14 at 16:51
  • I think your idea will work.. Can you please eloberate with a sample example of how COBOL program will call `funexit` fuction... I am new to shell script..! this could be greatly appreable.. – ANR Feb 25 '14 at 17:03
  • How your COBOL program would call `funexit` is entirely specific to COBOL, a language I've never used. You'll need to post a new question for advice on how to modify your COBOL program. – chepner Feb 25 '14 at 17:05
  • I just added an answer with `ACCEPT ... ON EXCEPTION`. The `ON EXCEPTION` conditional statements can then do a `STOP RUN GIVING 1` or maybe `ADD 1 TO RETURN-CODE` to tally up the missing fields, etcetera. – Brian Tiffin Feb 28 '14 at 03:53
0

Assign the output of your function to a variable outside the heredoc and check for failure there:

#!/bin/bash
funexit ()
{
    exit 1
}

if ! funexitvalue=$(funexit) ; then
    echo "Failure!"
    exit 1
fi


/caplus/pub/test123<<:EOD:
1
g
$funexitvalue
Y
:EOD:

This will prevent the COBOL program to be run if funexit does not exit successfully.

Explanation:

Command substitutions ($(...)) in bash always "work", as in, the substitution is replaced by the output of the command. Even if the command exits with an error:

$ echo "$(echo foobar; exit 1)"
foobar
$ echo $?
0

As you can see, the first echo exits successfully, even though the command in the substitution failed. The return code of the command substitution does not affect the actual command in any way.

In contrast:

$ a="$(echo foobar; exit 1)"
$ echo $?
1
$ echo $a
foobar

Here the return code of the command substitution is not shadowed by any other command, so you can actually check, if it returned successfully. Anyway, the assignment of the output to a was still successful.


Note: If you intended the COBOL program to be run up to the point where the faulty input would happen, than heredocs are not the way to go, as they are completely evaluated before they are even passed to the program. So with heredocs it is an all or nothing deal.

Adaephon
  • 16,929
  • 1
  • 54
  • 71
  • @Adaephon..! i have tried your suggestion but it does not work for me. It does not allow me to execute COBOL program. It is just displaying "Failure!" message to the terminal. My intension is to run the COBOL program and should get exit when an insufficient parameters were passed at runtime to the COBOL program. This could be here doc or could be any method. If you think this is not possible with here-doc, then could you please suggest me a good solution. – ANR Feb 25 '14 at 16:09
  • `#!/bin/bash funexit () { a="$(echo foobar; exit 1)" exit 1 } /caplus/pub/test123<<:EOD: 1 g 5 $(funexit) Y :EOD:` Tried as above but no luck COBOL program is accepting null value at the place of function call. it is not getting exit. – ANR Feb 25 '14 at 16:20
0

The heredoc is going to be parsed by the shell and passed as input in its entirety, and your approach is not going to work. However, you can certainly break up the input:

{ cat << EOF
This text will always be entered to the test123 executable;
EOF
funexit  # exit or return, as needed
cat << EOF
If funexit returned, this will go to test123.
If funexit exited, it will not
EOF
} | caplus/pub/test123
William Pursell
  • 204,365
  • 48
  • 270
  • 300