Jump to content

Ubuntu program auto restart [SH?]

So I have a windows RDP that has a batch file that auto restarts a jar file every 30 minutes. I want to do that with ubuntu but instead of every 30 minutes, I want it to restart on fail. The fail being that it loses connection to the site it is connecting to so it stops the program. I don't know if it should be in a .sh file or if there is some app to do it for me but I just want to know if it is possible. My friend told me to use the "watch" command in ubuntu but it never worked out.

 

So i now need an sh file that will restart a program every 30 minutes for ubuntu

Link to comment
https://linustechtips.com/topic/1268442-ubuntu-program-auto-restart-sh/
Share on other sites

Link to post
Share on other sites

You can do this with an "until" statement. Here's an example using SSH (not very useful, but it illustrates how you would do it):

 

#!/bin/sh

until ssh 192.168.1.1; do
	echo "SSH failed, retrying in 5 seconds..."; sleep 5
done

This will execute the ssh command after "until" repeatedly until the ssh command exits with an exit code of 0 (success). If the command exits with any other code, it will echo the "SSH failed text" text and wait 5 seconds before executing the ssh command again. Obviously, replace the ssh command with your own, and you can fiddle with the sleep timer as desired.

Link to post
Share on other sites

41 minutes ago, jsf said:

You can do this with an "until" statement. Here's an example using SSH (not very useful, but it illustrates how you would do it):

 


#!/bin/sh

until ssh 192.168.1.1; do
	echo "SSH failed, retrying in 5 seconds..."; sleep 5
done

This will execute the ssh command after "until" repeatedly until the ssh command exits with an exit code of 0 (success). If the command exits with any other code, it will echo the "SSH failed text" text and wait 5 seconds before executing the ssh command again. Obviously, replace the ssh command with your own, and you can fiddle with the sleep timer as desired.

I don't think that is what he needs. What he is looking for is to keep track of a process and rerun it when it dies.

 

1 hour ago, Khoomn said:

I still need help

 

Is there a specific type of executable you need to run or can it be anything? Writing a bash or c shell script for this is possible but pretty headache inducing. I would recommend writing a python script that uses os and subprocess library to monitor the exit_code of each subroutine call. It is much easier to program and a lot more flexible to be expanded than a shell script.

Link to post
Share on other sites

7 minutes ago, ATL said:

I don't think that is what he needs. What he is looking for is to keep track of a process and rerun it when it dies.

 

 

Is there a specific type of executable you need to run or can it be anything? Writing a bash or c shell script for this is possible but pretty headache inducing. I would recommend writing a python script that uses os and subprocess library to monitor the exit_code of each subroutine call. It is much easier to program and a lot more flexible to be expanded than a shell script.

That’s basically what this script will do. It will run the command at the top and wait for an exit code. If it dies with anything other than an exit code of 0, it will run it again.

 

If the OP needs to also run it again even in the case of an exit code of 0, it may take some more finagling but should be possible.

 

If there is some requirement that the script cannot also run the command to start the process then this method would not work (i.e you are starting it from rc or systemd on boot and need to track it after the fact)

Link to post
Share on other sites

15 minutes ago, jsf said:

That’s basically what this script will do. It will run the command at the top and wait for an exit code. If it dies with anything other than an exit code of 0, it will run it again.

 

If the OP needs to also run it again even in the case of an exit code of 0, it may take some more finagling but should be possible.

 

If there is some requirement that the script cannot also run the command to start the process then this method would not work (i.e you are starting it from rc or systemd on boot and need to track it after the fact)

I am not exactly sure what he needs, hence the "I don't think" and also why I suggested an easier and more flexible solution. I am just tossing ideas out there. In the case of run command, depends on what kind of process needs to be run, It is possible to parse the pid and echo the exit code if it is still alive. In the case of running on boot, create a service unit and systemctl enable it.

 

@Khoomnspecifically about the losing connection part, do you plan to do things on the server or simple maintaining connection? if the former is true, what kind of IO are you expecting? One way you can do it is to write a feedback loop connecting through TCP/IP using sockets with a programming language of your choice.

 

There is a myriad of options you could try. However, I do recommend taking project scale into consideration, this feature might not be worth the time to write a whole networking protocol around it.

 

 

Link to post
Share on other sites

2 hours ago, Sakuriru said:

He wants to run a program that will restart itself automatically when it crashes.

What kind of program? OP never specified. In the case of ssh, if he wants to do things on the server using -t and piping remote commands, their returns won’t be caught by the local machine.

 

2 hours ago, Sakuriru said:

In addition to his solution being simple, it is also very extensible. The best part of using a bash script the way described is that you're just wrapping your program with another program. That means you spin up a new process which can then has zero impact on the CPU until it's complete.

 

While I agree bash scripts has low overhead, you do know that ssh wastes both cpu and network bandwidth especially when your throughout is low, right? And also, wrappers are not exclusive to bash. As a matter of fact, there are syscall wrappers in the Linux kernel which is written in C. 

 

2 hours ago, Sakuriru said:

It's generally a bad idea to make a separate service that polls for a task and looks to restart it if it does not exist. Most of the time it's doing nothing but using system resources to determine that it needs to do nothing. In addition, it requires that it also be launched, increasing the program's configuration complexity.

LMAO, buddy. PID table in the Linux kernel use hashing which is constant time look up. It’s as cheap as you can get. Also I only suggest that in the case of run command process. And probably that’s the only case you will ever need to query PID table. 
 

Also speaking of configuration complexity, shell scripts are no better than any library based programming language. In the example script, there are no environment variable involved but in any scripts that are actually useful enough to warrant their existence, environment variable management is a nightmare.

Link to post
Share on other sites

@ATL I was just using ssh as an example of watching a command for an exit status and restarting it on failure. The OP could put any command there.

 

Though now that I re-read the original post, it sounds like the OP could accomplish this just by running the Java program in a tmux session and then detaching it. Then it doesn't matter if the ssh connection gets dropped later because it won't interrupt anything.

Link to post
Share on other sites

19 hours ago, Sakuriru said:

Yes, he did:

The difference between an interactive GUI and bare-bone TCP/IP. If you need explanation on why that makes a difference, enroll in or at least audit a full credits computer networks course at a credible university.

19 hours ago, Sakuriru said:

You do know that ssh was only being used as an example, right?

You do know that the purpose of giving an example is to make a point, right?

19 hours ago, Sakuriru said:

None of this is relevant and some of it doesn't even make sense.

I am sorry rudimentary computer science is too much for you. Read CLRS chapter 11.

19 hours ago, Sakuriru said:

I thoroughly recommend you actually understand something before critiquing it, especially when making bold claims like:

Umm, yeah, that's what @jsf's solution does. He also explained how it worked, so it's curious how you managed to come to this conclusion after reading his post.

 I provided reasoning for that suggestive "claim"(clearly you don't know what "I don't think" means) and offering an alternative approach. In the mean time, all you did was giving passive aggressive comments while contributing nothing to the subject of the OP.

At this point, I don't think you will post anything meaningful. So, to the "ignored" list you go.

Link to post
Share on other sites

Hey all, didn't realize there were so many comments, it can honestly be any kind of script, preferably it be python bc i can actually understand that, so the program I'm running is a simple .jar file, All i need it to do is if it dies or stops itself, have it re run the program so it is in an infinite loop of starting up when dying until i stop it manually.

 

I was told to use "watch" in ubuntu but it never worked for me.

Link to post
Share on other sites

12 hours ago, Sakuriru said:

So the problem with the watch command is that it's for the end user (that is, you). It's intended to display what a program is doing, or log it into a file. This isn't what you need though.

 

What you need is a wrapper for your jar file so that it will restart once it has crashed. I've made an example for you.

 

This is my program which intentionally crashes after 20 - 29 seconds.


public class Main {

    public static void main(String[] args) throws InterruptedException {

        int random = (int) (Math.random() * 10 + 20);

        System.out.printf("CrashApp: Sleeping for %s seconds.%n", random);
        Thread.sleep(random * 1000);

        System.out.println("CrashApp: Crashing application...");
        int crash = 1/0;
    }
}

 

Don't be afraid of bash! It's literally something you can just sort of stumble around with until it does what you want and it's not terribly complicated. It's actually going to make your life a lot easier and it's going to be easier with bash than it will with python. With bash your effectively interacting with the shell directly, which is where we want to be. I wrote a script that uses the same format found above.


#!/bin/sh

until java -jar CrashApp.jar; do
    echo "Bash: CrashApp crashed, restarting..."
    sleep 5
done

You could copy this verbatim, just simply replace CrashApp.jar with your jar file. Save this file as restart.sh or something similar in a directory you want to run. This directory should also contain the jar file you wish to run.

restart_script.thumb.png.9fa97592cb6d80c14c3d3997f294c1ff.png

As you can tell, it restarts automatically after crashing. Use Ctrl + C to cancel the execution of your script.

 

The only restriction here is that you'll need to leave open the terminal session or else it won't work. If you need to run this as a service (that is, run it without needing a terminal in the background), then let me know and I'll elaborate on running it as a daemon.

Hey - that's a pretty solid solution.

 

The best method to do that would probably be to create a screen and close it, as that will keep it running forever.

 

You can easily create a screen with "screen -S [screen name]" and once you started what you wanted, you can detach with CTRL A+D. You can see the screens running with "screen -list" and use "screen -R [screen name / ID]" from the list operation to get back into it. @Khoomn - wonder if this helps anything?

I'm streaming every day, many AAA games, to entertain people and to get a hang of games that others are unable to play or want to see before they buy. 

Check my profile for my ultimate rig! http://linustechtips.com/main/user/109708-shift/

Link to post
Share on other sites

On 11/17/2020 at 11:34 PM, Sakuriru said:

So the problem with the watch command is that it's for the end user (that is, you). It's intended to display what a program is doing, or log it into a file. This isn't what you need though.

 

What you need is a wrapper for your jar file so that it will restart once it has crashed. I've made an example for you.

 

This is my program which intentionally crashes after 20 - 29 seconds.


public class Main {

    public static void main(String[] args) throws InterruptedException {

        int random = (int) (Math.random() * 10 + 20);

        System.out.printf("CrashApp: Sleeping for %s seconds.%n", random);
        Thread.sleep(random * 1000);

        System.out.println("CrashApp: Crashing application...");
        int crash = 1/0;
    }
}

 

Don't be afraid of bash! It's literally something you can just sort of stumble around with until it does what you want and it's not terribly complicated. It's actually going to make your life a lot easier and it's going to be easier with bash than it will with python. With bash your effectively interacting with the shell directly, which is where we want to be. I wrote a script that uses the same format found above.


#!/bin/sh

until java -jar CrashApp.jar; do
    echo "Bash: CrashApp crashed, restarting..."
    sleep 5
done

You could copy this verbatim, just simply replace CrashApp.jar with your jar file. Save this file as restart.sh or something similar in a directory you want to run. This directory should also contain the jar file you wish to run.

restart_script.thumb.png.9fa97592cb6d80c14c3d3997f294c1ff.png

As you can tell, it restarts automatically after crashing. Use Ctrl + C to cancel the execution of your script.

 

The only restriction here is that you'll need to leave open the terminal session or else it won't work. If you need to run this as a service (that is, run it without needing a terminal in the background), then let me know and I'll elaborate on running it as a daemon.

Thank you! I will try this and get back to you if it works.

 

12 hours ago, SHiFT said:

Hey - that's a pretty solid solution.

 

The best method to do that would probably be to create a screen and close it, as that will keep it running forever.

 

You can easily create a screen with "screen -S [screen name]" and once you started what you wanted, you can detach with CTRL A+D. You can see the screens running with "screen -list" and use "screen -R [screen name / ID]" from the list operation to get back into it. @Khoomn - wonder if this helps anything?

Yeah, thats what I intend on doing it with.

Link to post
Share on other sites

On 11/17/2020 at 11:34 PM, Sakuriru said:

So the problem with the watch command is that it's for the end user (that is, you). It's intended to display what a program is doing, or log it into a file. This isn't what you need though.

 

What you need is a wrapper for your jar file so that it will restart once it has crashed. I've made an example for you.

 

This is my program which intentionally crashes after 20 - 29 seconds.


public class Main {

    public static void main(String[] args) throws InterruptedException {

        int random = (int) (Math.random() * 10 + 20);

        System.out.printf("CrashApp: Sleeping for %s seconds.%n", random);
        Thread.sleep(random * 1000);

        System.out.println("CrashApp: Crashing application...");
        int crash = 1/0;
    }
}

 

Don't be afraid of bash! It's literally something you can just sort of stumble around with until it does what you want and it's not terribly complicated. It's actually going to make your life a lot easier and it's going to be easier with bash than it will with python. With bash your effectively interacting with the shell directly, which is where we want to be. I wrote a script that uses the same format found above.


#!/bin/sh

until java -jar CrashApp.jar; do
    echo "Bash: CrashApp crashed, restarting..."
    sleep 5
done

You could copy this verbatim, just simply replace CrashApp.jar with your jar file. Save this file as restart.sh or something similar in a directory you want to run. This directory should also contain the jar file you wish to run

restart_script.thumb.png.9fa97592cb6d80c14c3d3997f294c1ff.png

As you can tell, it restarts automatically after crashing. Use Ctrl + C to cancel the execution of your script.

 

The only restriction here is that you'll need to leave open the terminal session or else it won't work. If you need to run this as a service (that is, run it without needing a terminal in the background), then let me know and I'll elaborate on running it as a daemon.

so it runs, but it doesnt restart it.

 

this is what my sh file looks like. I feel like something is wrong as its not telling the program to restart

#!/bin/sh

until java -jar Discordbot.jar; do
	echo "Bash: CrashApp crashed, restarting..."; 
	sleep 1
done

 

Link to post
Share on other sites

On 11/19/2020 at 11:56 PM, Sakuriru said:

What's the exit code from your Discordbot.jar program?

You can view it like this:
 


java -jar Discordbog.jar
echo $?

 

So ontop of the fact that the program surprisingly still works lol, i did that and it just says 0 then stops.

Screenshot_182.png

Link to post
Share on other sites

  • 4 weeks later...
On 11/21/2020 at 10:56 AM, Sakuriru said:

Aha, so the problem here is that your script is exiting normally, or the programmer is improperly exiting with a zero code when it encountered an error. That's why the script isn't working. The idea behind the other idea is that we want to allow your script to exit normally, but in this case I guess we have to do a nono and make it run in an infinite loop.

Use this instead:


#!/bin/sh

while true; do
    java -jar Discordbot.jar
    echo "Bash: Discordbot quit, restarting..."
    sleep 5
done

Hey im opening this back up because I need almost the same thing with a different parameter. I need it to restart every X amount of minutes, doesnt matter if its active or not, just close the program and open it back up. I feel it should be as simple as the last but just need to know. Thanks

Link to post
Share on other sites

  • 2 weeks later...
On 12/14/2020 at 3:09 PM, Khoomn said:

Hey im opening this back up because I need almost the same thing with a different parameter. I need it to restart every X amount of minutes, doesnt matter if its active or not, just close the program and open it back up. I feel it should be as simple as the last but just need to know. Thanks

 

Here's a simple example using xterm as the program to restart. This will launch xterm, and put it in the background. It will then enter the while loop. First, it waits 5 seconds (change this value to the number of seconds you want to let the process run). Then it kills the xterm process based on its name ("pkill"' will kill it based on its name, whereas "kill" would need its PID). It waits 1 second, then starts xterm again and begins the loop over.

#!/bin/sh

xterm &

while true
do
	sleep 5
	pkill xterm
	sleep 1
	xterm &
done

Obviously, change xterm to your program and make sure you are pkilling the right process name.

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×