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

  • 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 '18 at 11:36
  • 3
    What's your objective of using return 0 and return 1 in the script? – User123 Dec 28 '18 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. – User123 Dec 28 '18 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. – Govinda Sakhare Dec 29 '18 at 8:41
  • 3
    So please update your question with these clarifications. Make it easy for us to help you. – roaima Dec 29 '18 at 15:42
1
+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.

  • This solution is not working. Script is still running in the background. I check with ps -aux and script is not exiting. – Govinda Sakhare Dec 31 '18 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 '18 at 7:29
  • What happens if you replace the java with, for example, ls? – ctrl-alt-delor Jan 1 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 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). – ctrl-alt-delor Jan 1 at 11:14
1

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
  • 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. – Govinda Sakhare Dec 30 '18 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. – User123 Dec 30 '18 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 – Govinda Sakhare Dec 31 '18 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

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.

-1

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.