2

Just looking for a correction/addition to this cannibalized restart code for (originally a Minecraft server, though that is not what it's used for now).

 @echo off
title Server Restarter
color 0A
cls
@%SystemRoot%\system32\ping.exe -n 1 xxx.xxx.x.xx
pause

:start
Call Server.bat
cls
pause

This currently does a very simple job: calls server.bat and starts the server. It has none of the bells and whistles I'd like it to have though. The output of ping is not functional at the moment.

The goal:

  1. Ping to see if a specific IP (and maybe ports) are reachable.

  2. If they are not reachable, close any current instances of Server.exe

  3. Continue pinging until specific IP is reachable.

  4. Once the IP is reachable, call server.bat

It needs to ping at intervals of ~30 seconds.

Some context for why it's needed:

The game server does not currently close its process regardless of it being online or not, it continues to run in the process window. That's why I need it close any current instances, else we just end up with multiples of the same server running.

The server is run from a local computer using direct IP connection, therefore if the local computer isn't connected to the internet, the server wont be reachable to anyone (obviously). The intent for the .bat is to run continuously so even when the user isn't at the computer, it will take care of ensuring the server is online 24/7.

This will be a file I will want to make available to other server hosts who may want to use it to keep themselves online 24/7.

The port check will be to ensure the master server ports are reachable and the fault is/isn't on their side, this is not essential so if it's too much trouble, don't worry.

Inside "Server.bat":

@echo off
echo Server process starting
echo Ctrl+Alt+Del to Kill
Server.exe -batchmode -nographics

All of your assistance and comments are very much welcomed. I tried to generalize this as much as possible to keep it simple, so it can be altered for anyone else who may find use for it with any application.

YetAnotherRandomUser
  • 1,320
  • 3
  • 13
  • 31
Cinn
  • 71
  • 1
  • 11
  • First off: you don't need the `@` in the `ping` command. Secondly, you can use `&` or `|` operator to detect if ping succeded or not. You can also try `%errorlevel%` variable. –  Jul 21 '17 at 00:57
  • @SteveFest Sorry, I don't quite understand, where/how would I use `%errorlevel%` or `&` `|` My level of batch understanding is unquestionably limited. – Cinn Jul 21 '17 at 02:55
  • go to ss64.com/nt and you can find those out –  Jul 21 '17 at 02:59
  • @SteveFest I see, I may have not been clear enough, I apologize. This is determining if it has successfully executed the ping command. Not whether the return ping itself was successful. E.g, sent packet x1 // received packet x1 = lost 0 or sent packet x1 // did not receive packet x1 = lost 1 – Cinn Jul 21 '17 at 03:13
  • Well. alternatively, you can use a for loop to retrieve the command result, and you can determine if ping is successful(a failure ping comes with specific text, and you can check if ping result comes with such text.) –  Jul 21 '17 at 03:17
  • Note: I mean `for /f` loop –  Jul 21 '17 at 03:19
  • @SteveFest Thanks, this seems to be what I want, now it's trying to make it do a kind of IF not 100 then Call start. I've got it working right (ish): `set _ping_cmd=ping -n 1 XXX.XX.XX.XX FOR /f "tokens=5 delims=(=" %%G IN ('%_ping_cmd% ^|find "100"') DO echo %Result% is [%%G] pause :start Call Server.bat cls pause` The pause is just so I can see its readout, now all it needs is the &&/| | operator(s), because it will run Server.bat regardless of the result, but it is now correctly looking for the result of the ping. – Cinn Jul 21 '17 at 04:20
  • In your `for` loop, you can try an `if` statement like so: if the result is not 100, start server.bat... –  Jul 21 '17 at 04:21
  • Or more precisely: `..."100"') DO if not %result% equ 100 call server.bat` –  Jul 21 '17 at 04:24
  • @SteveFest, I accidentally put the echo Result into %result% in my attempts to get it to respond to the readout, but quickly realized result isn't any kind of variable.. Instead I'm trying to get to use IF %%G equ 100 call Server.bat but that wont work either. My current line looks like: `FOR /f "tokens=5 delims=(=" %%G IN ('%_ping_cmd% ^|find "100"') DO echo Result is [%%G]` – Cinn Jul 21 '17 at 04:48
  • What do you get if you `echo %%G`? –  Jul 21 '17 at 04:49
  • Echoing %%G after `DO echo Result is [%%G] displays " %G " – Cinn Jul 21 '17 at 04:55
  • So you are comparing `100% loss` with `100`. That's incorrect, try to trim the result with `..delims=(= "` so that you will compare `100` with `100`. –  Jul 21 '17 at 04:56
  • Can't get to grips with delims and tokens, even with ss64.com This is as far as I could trim it: https://i.gyazo.com/3d3ec415c87951ccc66eaa069dab02c7.png – Cinn Jul 21 '17 at 05:48
  • Use variable substring and delayedexpansion. Put the following in the 2nd line of your file: `setlocal enableDelayedExpansion`. Then change your `for` loop like so: http://imgur.com/WaBogqe –  Jul 21 '17 at 05:53
  • Note: you have to add the `if` statement after the two set statements. –  Jul 21 '17 at 05:54
  • @SteveFest Okay, no result, this feels spaghetti-ish. must have missed something... https://i.gyazo.com/7e8bb10ff75a239b3d0782e5d3465b81.png – Cinn Jul 21 '17 at 06:13
  • Okay. Take a look in this completed script: http://imgur.com/2N4z8zh –  Jul 21 '17 at 06:16
  • @SteveFest Reporting it's unable to find 'Server.bat' which is odd, the Restart.bat is located in the same folder as Server.bat.... https://i.gyazo.com/fecd4b40abd6afee731ee22e46e93a82.png – Cinn Jul 21 '17 at 06:28
  • Aw... My fault - :server.bat should be server.bat –  Jul 21 '17 at 06:29
  • @SteveFest Progress! However... It runs fine when the IP is connectable (I assume because it's finding the '100', however, when the IP is not connectable (internet disconnected) it throws up an error. The window to the left is non-connectable IP, on the right connectable IP. https://i.gyazo.com/dc0a2e6816e85074948f50ee761f375e.png – Cinn Jul 21 '17 at 06:39
  • The main problem is how you phase the `if` statement. At first, you can get `100%`, so why not try `if not "%%G" == "100%"? You don't need extra work then. –  Jul 21 '17 at 06:43
  • @SteveFest Attempted both here.. 1. this one returns desired result of 100%, but has no function to start server.bat because of it. https://i.gyazo.com/d45e26e16275ff3ef2e6689f53c0d68e.png 2. I attempted the IF statement you made. https://i.gyazo.com/6264f0cba265dbd22a856ee397099d6f.png You can try (if you wish) to run just a basic text file with :start [textfile].txt and if it manages to open a text file based on '100%' return of an IP address then you will know if it works. – Cinn Jul 21 '17 at 07:28
  • **No!!!!** If statement doesn't work like that - read ss64 –  Jul 21 '17 at 07:30
  • @SteveFest Have I got it here? https://i.gyazo.com/34a9338ee50090b400f2592f53469203.png Not running the server.bat however. – Cinn Jul 21 '17 at 08:08
  • Ended up making this: `@echo off title Server Restarter color 0A cls :start Echo Enter Server IP: set /p ip=122.58.141.21 :ping ping %ip% -n 1 || goto Starting echo Ping was Successful to %ip% at %date% %time% goto set if %ERRORLEVEL%==2 GOTO :EOF cls pause :Starting Echo Ping failed... Start Server.bat || goto start Echo Start Successful goto ping pause` Need to fix the... infinite looping... – Cinn Jul 21 '17 at 14:24

1 Answers1

1

Sounds like you're working on or with a Windows machine. Power Shell might be an option to write your scripts. I came across this question after investigating Test-Connection and Test-NetConnection, which are both kind of like ping, and the latter lets you test if a port is open. Not sure if there are batch file commands like those, but Power Shell lets you use most batch commands. Both of these commands have tons of examples online, and are very easy to use in your use-case.

You probably want to have a while (true) loop running, and periodically do your ping/port checks. That will satisfy your continual checking requirement. Start-Sleep is a cmdlet to let you pause your script, which you'll want to do in your forever loop.

You can call batch files from Power Shell (another link from another good resource), so that will let you reuse your existing scripts if you don't want to rewrite them in Power Shell.

YetAnotherRandomUser
  • 1,320
  • 3
  • 13
  • 31