如何优雅的实现Java启动与停止脚本(.bat与.sh 脚本)
程序目录结构参考:
windows操作系统下,在run.bat所在目录下打开dos窗口(cmd.exe),输入run.bat,回车即可运行程序(双击run.bat也可运行程序)
run.bat:
1 @title My APP 2 @echo off 3 setlocal enabledelayedexpansion 4 set JAVA=jre1.6.0_45\bin\java.exe 5 set OPTS=-Xms2048M -Xmx2048M -Xss512k -XX:+AggressiveOpts -XX:+UseParallelGC -XX:NewSize=64M -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:gc.log -XX:+HeapDumpOnOutOfMemoryError 6 set LIBPATH=lib 7 set ENGINE=. 8 set CP=%ENGINE%;conf 9 set MAIN=xxx.xxx.xxx.Main 10 11 12 for /f %%i in ('dir /b %LIBPATH%\*.jar^|sort') do ( 13 set CP=!CP!;%LIBPATH%\%%i 14 ) 15 16 echo =============================================================================== 17 echo. 18 echo Engine Startup Environment 19 echo. 20 echo JAVA: %JAVA% 21 echo. 22 echo JAVA_OPTS: %OPTS% 23 echo. 24 echo CLASSPATH: %CP% 25 echo. 26 echo =============================================================================== 27 echo. 28 29 @echo on 30 %JAVA% %OPTS% -classpath %CP% %MAIN%
带界面的 GUI 程序
如果 java 程序是带界面的GUI程序,建议使用 javaw.exe 运行(即 set JAVA=jre1.6.0_45\bin\javaw.exe )。
脚本如下:
1 ::author@oldpub 2 ::ANSI file encoding is required under windows OS 3 @title My APP 4 @echo off 5 setlocal enabledelayedexpansion 6 set JAVA=jre1.6.0_45\bin\javaw.exe 7 set OPTS=-Xms2048M -Xmx2048M -Xss512k -XX:+AggressiveOpts -XX:+UseParallelGC -XX:NewSize=64M -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:gc.log -XX:+HeapDumpOnOutOfMemoryError 8 set LIBPATH=lib 9 set ENGINE=. 10 set CP=%ENGINE%;conf 11 set MAIN=xxx.xxx.xxx.Main 12 13 for /f %%i in ('dir /b %LIBPATH%\*.jar^|sort') do ( 14 set CP=!CP!;%LIBPATH%\%%i 15 ) 16 echo. 17 echo =============================================================================== 18 echo. 19 echo Engine Startup Environment 20 echo. 21 echo JAVA: %JAVA% 22 echo. 23 echo JAVA_OPTS: %OPTS% 24 echo. 25 echo CLASSPATH: %CP% 26 echo. 27 echo =============================================================================== 28 echo. 29 30 @echo on 31 start %JAVA% %OPTS% -classpath %CP% %MAIN% 32 @echo off 33 echo. 34 echo =============================================================================== 35 echo. 36 echo 即将打开程序,请耐心等待...... 37 echo. 38 echo =============================================================================== 39 @timeout 5
windows下关闭进程的 bat 脚本
有时候会遇到需要定时重启程序的需求,若此时无法人工手动叉掉进程窗口,需要提供stop脚本,有两种方式如下(推荐方式二):
1 @echo off & setlocal EnableDelayedExpansion 2 :: 方式一:根据端口号强制杀进程(关闭监听了8080端口号的进程): 3 for %%a in (9080) do ( 4 set pid=0 5 for /f "tokens=2,5" %%b in ('netstat -ano ^| findstr ":%%a"') do ( 6 set temp=%%b 7 for /f "usebackq delims=: tokens=1,2" %%i in (`set temp`) do ( 8 if %%j==%%a ( 9 taskkill /f /pid %%c 10 set pid=%%c 11 echo process.prot=[%%a] is killed 12 ) 13 ) 14 ) 15 ) 16 exit
1 @echo off 2 :: 方式二:根据主类名称找到进程号,然后杀进程 3 setlocal 4 set JPS=jps 5 set MAIN_CLASS=xxx.xxx.xxx.Main 6 7 for /f "tokens=1" %%a in ('%JPS% -l ^| findstr /i "%MAIN_CLASS%"') do ( 8 set PID=%%a 9 ) 10 11 if defined PID ( 12 echo Stopping %MAIN_CLASS% PID %PID%... 13 :: taskkill /f /pid %PID% 代表强制杀进程。 14 :: 如果不希望强制杀进程,而是希望发送一个关闭信号给进程,让进程优雅退出(相当于 ctrl + c)。可将命令替换为 windows-kill -2 %PID% 15 :: 优雅退出的方式需要依赖一个 windows-kill.exe 程序(可在github下载:https://github.com/ElyDotDev/windows-kill/releases/tag/1.1.4) 16 taskkill /f /pid %PID% 17 echo %MAIN_CLASS% is stopped. 18 exit 19 ) else ( 20 echo %MAIN_CLASS% is not running. 21 ) 22 23 endlocal
Linux操作系统下,执行 ./run.sh start 启动程序; ./run.sh stop 停止程序; ./run.sh restart 重启程序
[root@centos7 MyAPP]# ./run.sh start
[root@centos7 MyAPP]# ./run.sh stop
[root@centos7 MyAPP]# ./run.sh restart
run.sh:
1 #!/bin/bash 2 export APP_DIR=$(cd $(dirname $0); pwd) 3 export CP=${APP_DIR}:${APP_DIR}/conf:`find ${APP_DIR}/lib -name "*.jar" |xargs|sed "s/ /:/g"` 4 export MAIN=xxx.xxx.xxx.Main 5 6 export JAVA=java 7 export OPTS="-Xms2048M -Xmx2048M -Xss512k -XX:+AggressiveOpts -XX:+UseParallelGC -XX:NewSize=64M -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:gc.log -XX:+HeapDumpOnOutOfMemoryError" 8 9 mainPID=0 10 11 getMainPID(){ 12 javaps=`ps -ef |grep java|grep $MAIN|grep $APP_DIR|grep -v grep` 13 if [ -n "$javaps" ]; then 14 mainPID=`echo $javaps |awk '{print $2}'` 15 else 16 mainPID=0 17 fi 18 } 19 20 startup() 21 { 22 getMainPID 23 if [ $mainPID -ne 0 ]; then 24 echo "App is already started(PID=$mainPID)" 25 else 26 cd ${APP_DIR} 27 $JAVA $OPTS -classpath $CP $MAIN & 28 getMainPID 29 cd - 1>/dev/null 2>&1 30 echo "App has been started(PID=$mainPID)" 31 fi 32 } 33 34 shutdownapp() 35 { 36 getMainPID 37 if [ $mainPID -ne 0 ]; then 38 echo "Try to stop, please wait ..." 39 # kill -9 $mainPID 代表强制杀进程 40 # 如果不希望强制杀进程,而是希望发送一个关闭信号给进程,让进程优雅退出。可将命令替换为 kill -15 $mainPID 41 kill -9 $mainPID 42 getMainPID 43 if [ $mainPID -ne 0 ]; then 44 shutdownapp 45 fi 46 echo "App has been stopped" 47 else 48 echo "App is not running" 49 fi 50 } 51 52 case "$1" in 53 start) 54 startup 55 ;; 56 stop) 57 shutdownapp 58 ;; 59 restart) 60 $0 stop 61 $0 start 62 ;; 63 *) 64 echo "Usage:" 65 echo "./run.sh start/stop/restart" 66 exit 1;; 67 esac
其他:
除了脚本运行的方式,还可以打包成可执行程序,例如:
exe4j
launch4j
jPackage,jdk14新发布,面向java桌面端程序打包. 可以让windows/mac 直接双击使用java程序,不要求事先安装jdk/jre.
推荐阅读: