2

I have an autosys job. In the autosys job I am executing a shell script. Shell script executes indefinitely running java program. Say infinite for loop.

#!/bin/ksh

function abc() {
    java DemoJavaProgram
    RESULT=$?
    if[ $RESULT -eq 0 ]; then
        exit 0;
    else
        exit 1;
}
abc | tee output.file

Above shell script is not returning anything instead it is stuck at running java program. Due to this autosys job status is RUNNING

I tried running above command in the background with & I had no success. I tried running an entire shell script in the background, even in this case also I had no success.

is there any way to exit from such script.

[tl;dr] I want to start the java program and exit the script

7
  • 5
    You're checking the exit status code of a java program that never exits? Do you just want to start the java program in the background and exit the script?
    – Haxiel
    Dec 28, 2018 at 11:36
  • 3
    What's your objective of using return 0 and return 1 in the script?
    – ashish_k
    Dec 28, 2018 at 11:37
  • With this program, it's obvious that your Autosys job will continue running, because your code is just checking the exit status(0) of the java program which was started successfully and your if condition is just evaluating to to true all the time.
    – ashish_k
    Dec 28, 2018 at 11:40
  • @Haxiel You got me right. I want to start the java program and exit the script. I don't mind removing if-else block from the code. Dec 29, 2018 at 8:41
  • 3
    So please update your question with these clarifications. Make it easy for us to help you.
    – roaima
    Dec 29, 2018 at 15:42

6 Answers 6

2
+50

I am not familiar with autosys itself, but you can start a long-running command in the background like this:

#!/bin/ksh
nohup java DemoJavaProgram 1> output.file 2>&1 </dev/null &

The nohup command allows the java command to survive hangup signals. The input and output are then redirected. The & operator at the end forces the command to run in the background.

Do note that you will not be able to depend upon the exit status code here. If the java command fails to start for some reason, it will write the error message to the output file and exit.

8
  • This solution is not working. Script is still running in the background. I check with ps -aux and script is not exiting. Dec 31, 2018 at 4:42
  • @GovindaSakhare Can you elaborate? If I put this command inside a script, say test.sh and run ./test.sh, I get the intended result. The command inside the script continues running, while the script itself does not. How does your approach differ?
    – Haxiel
    Dec 31, 2018 at 7:29
  • What happens if you replace the java with, for example, ls? Jan 1, 2019 at 0:01
  • @GovindaSakhare My example syntax was previously not valid for a ksh environment. Sorry about that. Can you take a look at the edit and see if it works for you now?
    – Haxiel
    Jan 1, 2019 at 4:51
  • 1
    @Haxiel, sorry that comment was not for you. It is for the OP. I think that if your answer does not work, then answering the question I pose in the comment, may find the problem (so long at they do the experiment for real, not in their head). Jan 1, 2019 at 11:14
2

As per your requirement, you need to replace return functions with exit:

Can you try below and check:

#!/bin/ksh
java DemoJavaProgram
RESULT=$?
if [ "$RESULT" -eq 0 ]
 then
    echo "SUCCESS"
exit 1
else 
echo "FAILURE"
fi
3
  • what the point in echo SUCCESS. The script will keep running as DemoJavaProgram runs for an indefinite period of time. besides that Autosys looks for the script to exit gracefully. Dec 30, 2018 at 10:48
  • @GovindaSakhare: Yes, you can remove the echo SUCCESS part from the script, i just added it for the descriptive purpose, also it'll neither affect your requirement of exiting the script on the successful starting of the java program nor your Autosys job. Your Autosys job will exit gracefully and if you think of configuring the log path/name for this Autosys job, then this echo part (you can include the description as per your convenience)will come as handy to you or to your team ,just to validate that the script started without any issue.
    – ashish_k
    Dec 30, 2018 at 16:14
  • Solution is not working, script is still running in the background, exit 1 is not terminating the script process. I checked using ps -aux | grep scriptName.ksh. Autosys job status is also RUNNING Dec 31, 2018 at 4:44
0

I'm not familiar with autosys either, but one hack that can be used to start long-running programs from udev rules or from a user session (and work around systemd killing background jobs despite nohup) is using the the at(1) command.

echo your_cmd | at now

Any output from the your_cmd will be mailed to the user running it. If you don't like that, you can use redirects:

echo 'your_cmd >/dev/null 2>/path/to/errorlog' | at now

The at from linux also has a non-standard -M option for that:

echo 'your_cmd' | at -M now # ignore any output

Unfortunately, there's no option to shut up at's informational messages, so you'll have to filter them out yourself:

#! /bin/sh
function run_with_at(){
    echo "$@" | at now 2>&1 |
        egrep >&2 -v '^warning: commands will be executed using /bin/sh$|^job [0-9]+ at'
}
run_with_at 'java DemoJavaProgram >/dev/null' # any stderr output will still be mailed to the user
0

There is no way to control a process by checking its result. The link describes how to control the run time, and do various checks. https://stackoverflow.com/questions/5161193/how-to-kill-a-child-process-after-a-given-timeout-in-bash

0

As far as I understand your start script, you do not need it. Simple start your java program with redirection like this.

java DemoJavaProgram >output.txt

Every output of your Java program System.out.print* will occur in the output.txt file. If you need also the System.err.print* in your output.txt, append also 2>&1 or if you would like to have the error output in an extra file add 2>failure.txt or if you really do not need the error output add 2>/dev/null

If you need to start it in background, append &.

If you start it from an other system, use nohup as mentioned by @Haxiel.

nohup java DemoJavaProgram 1> output.file 2>&1 </dev/null &

If you need to take a look in the output.txt after a while: tail -f output.txt will show last 10 lines of output.txt and continued.

0

The question is a bit puzzling to me, not in the least because of the pipe (to tee) that you apparently wish to use. To maintain this functionality, you could use the following script:

#!/bin/ksh
tee output.file < <( java DemoJavaProgram ) &

That's it. The script will terminate, the java program will continue to run in the background, and data output by the java program on stdout will be copied to both stdout and output.file.

I note that simply running ps -aux | grep scriptName.ksh may mislead you into believing that the script is still running, since the process substitution <(...) is likely run in/from a subshell process that bears the name of the original script, but is actually a child of tee. The parent, i.e. the above script, will have died, as should be apparent from the PPID (i.e. Parent PID) value that you can inspect with, for instance, ps -o pid,ppid,tty,comm -H.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .