Windows: bat-файл для остановки Tomcat с помощью taskkill

Автор: | 11/07/2013
 

windows_logoОдна из сборок Apache Tomcat отказывается останавливаться стандартным shutdown.bat:

>shutdown.bat
Using CATALINA_BASE:   C:Opttomcat_8080
Using CATALINA_HOME:   C:Opttomcat_8080
Using CATALINA_TMPDIR: C:Opttomcat_8080temp
Using JRE_HOME:        C:Optjdk1.6.0_32x64jre
Using CLASSPATH:       C:Opttomcat_8080binbootstrap.jar
The process cannot access the file because it is being used by another process.

Оставалось несколько tread-ов в памяти, и Tomcat висел в процессах.

Конечно, можно «убить» процесс вручную, но в данном случае все действия должны выполняться автоматически, с сервера TeamCity.

Первая проблема состоит в том, что Tomcat запускается Java-ой и этот процесс никак не отличается от других:

>tasklist /v /FI "IMAGENAME eq java.exe"

Image Name                     PID Session Name        Session#    Mem Usage Status          User Name                                              CPU Time Window Title

========================= ======== ================ =========== ============ =============== ================================================== ============ ======================
================
java.exe                       692 RDP-Tcp#0                  1      2,556 K Running         lms-build1user                                         0:00:04 TeamCity Build Agent

java.exe                      1572 RDP-Tcp#0                  1     89,304 K Unknown         lms-build1user                                         0:10:08 N/A

java.exe                      3220 RDP-Tcp#0                  1    797,072 K Unknown         lms-build1user                                         0:01:03 N/A

Для решения — выполним небольшой «тюнинг» файла startup.bat, которым выполняется запуск Tomcat.

В начале скрипта добавим строку:

set title="Tomcat"

Посмотрим ещё раз:

>tasklist /v /FI "IMAGENAME eq java.exe"

Image Name                     PID Session Name        Session#    Mem Usage Status          User Name                                              CPU Time Window Title

========================= ======== ================ =========== ============ =============== ================================================== ============ ========================================================
================
java.exe                       692 RDP-Tcp#0                  1      2,556 K Running         lms-build1user                                         0:00:04 TeamCity Build Agent

java.exe                      1572 RDP-Tcp#0                  1     89,364 K Unknown         lms-build1user                                         0:10:08 N/A

java.exe                      1724 RDP-Tcp#0                  1    254,052 K Running         lms-build1user                                         0:00:43 Tomcat

Теперь последний процесс Java имеет Title Tomcat, по которому мы сможем выбрать именно этот процесс и не уничтожить, например, запущенный BuildAgent от TeamCity.

Теперь — создадим пустой файл, в который будем записывать вывод tasklist:

>type NUL > tomcatpid.txt

Далее воспользуемся командой tasklist с фильтрами, и полученные данные запишем в созданный файл:

>tasklist /v /FI "IMAGENAME eq java.exe" | findstr /i "Tomcat" > tomcatpid.txt

Смотрим содержимое файла:

>type tomcatpid.txt
java.exe                      3360 RDP-Tcp#0                  1    102,896 K Running         lms-build1user                                         0:00:10 Tomcat

А следующей командой — уничтожим PID Tomcat-а:

>for /F "TOKENS=2" %a in ('type tomcatpid.txt') do (taskkill /PID %a)

>(taskkill /PID 3360 )
SUCCESS: Sent termination signal to the process with PID 3360.

Проверим:

>tasklist /v /FI "IMAGENAME eq java.exe"

Image Name                     PID Session Name        Session#    Mem Usage Status          User Name                                              CPU Time Window Title

========================= ======== ================ =========== ============ =============== ================================================== ============ ========================================================
================
java.exe                       692 RDP-Tcp#0                  1      2,556 K Running         lms-build1user                                         0:00:04 TeamCity Build Agent

java.exe                      1572 RDP-Tcp#0                  1     89,324 K Unknown         lms-build1user                                         0:10:08 N/A

Tomcat-а нет.

Осталось всё это собрать в один скрипт:

>type deploy.bat

set CURR_DIR=%cd%
set CATALINA_HOME=C:OptTomcatsapache-tomcat-6.0.37_clear_install

call %CATALINA_HOME%start_config_.bat

:: Создаём пустой файл, в который запишем процесс Tomcat
type NUL > tomcatpid.txt

:: Получаем список процессов, выбираем Tomcat, записываем его в файл
tasklist /v /FI "IMAGENAME eq java.exe" | findstr /i "Tomcat" > tomcatpid.txt

::Выбираем PID процесса и выполняем taskkill Tomcat-а
for /F "TOKENS=2" %%a in ('type tomcatpid.txt') do (taskkill /PID %%a)

:: Удаляем файл
del tomcatpid.txt

:: Удаляем рабочий каталог Tomcat-а со всем содержимым и создаём его заново
rmdir /S /Q %CATALINA_HOME%webappsROOT
mkdir %CATALINA_HOME%webappsROOT

:: Копируем собранные Maven-ом файлы в рабочий каталог Tomcat-а
for /d %%d in (%CURR_DIR%app-webtargetapp-web-*) do (
  xcopy /S /E %%d* %CATALINA_HOME%webappsROOT
)

:: И запускаем Tomcat
call %CATALINA_HOME%binstartup.bat