Как остановить запущенный jar-файл в bash-скрипте через 5 минут и запустить следующий?

2102
Hk148

Я должен запустить файл JAR с различными параметрами, как это:

#!/bin/bash cd /Users/hawkarhama/Desktop/RUN  echo $(java -jar IPM.jar 0 20 3 sign.txt) echo $(java -jar IPM.jar 1 20 3 sign.txt) echo $(java -jar IPM.jar 2 20 3 sign.txt) 

Если, скажем, второй занял больше пяти минут, я хочу остановить его и перейти к следующему. Таким образом, максимальное время для каждого кувшина составляет 5 минут. Если это займет меньше, это нормально; но если он выполняется дольше, сценарий должен перейти к следующему.

1
(1) Если вы спрашиваете * конкретно * о программе Java, которую вы можете изменить, один из подходов может заключаться в том, чтобы встроить ограничение по времени в код Java. (2) Почему вы говорите `echo $ (…)` вместо того, чтобы просто запустить программу с `java -jar IPM.jar… sign.txt`? G-Man 9 лет назад 0
Для `echo $` вы правы, и я делал это до того, как это была просто копия кода, который я поместил здесь. Что касается кода Java, я не знаю, как это сделать программно. Я пробовал `System.CurrentTimeMilles`, но он не работает. Hk148 9 лет назад 0

2 ответа на вопрос

1
NuTTyX

Это должно работать в Bash 4 или более поздней версии:

#!/bin/bash cd /Users/hawkarhama/Desktop/RUN  ( cmdpid=$BASHPID; (sleep 300; kill $cmdpid ) & exec java -jar IPM.jar 0 20 3 sign.txt ) ( cmdpid=$BASHPID; (sleep 300; kill $cmdpid ) & exec java -jar IPM.jar 1 20 3 sign.txt ) ( cmdpid=$BASHPID; (sleep 300; kill $cmdpid ) & exec java -jar IPM.jar 2 20 3 sign.txt ) 

Для предыдущих версий:

#!/bin/bash cd /Users/hawkarhama/Desktop/RUN  bash -c '(sleep 300; kill $$) & exec java -jar IPM.jar 0 20 3 sign.txt' bash -c '(sleep 300; kill $$) & exec java -jar IPM.jar 1 20 3 sign.txt' bash -c '(sleep 300; kill $$) & exec java -jar IPM.jar 2 20 3 sign.txt' 

После поиска немного чистой версии Java, я нашел это :

ScheduledExecutorService executor = Executors.newScheduledThreadPool(2);  final Future handler = executor.submit(new Callable(){  DoStuffHere(); }); executor.schedule(new Runnable(){ public void run(){ handler.cancel(); }  }, 5*60*1000, TimeUnit.MILLISECONDS); 
спасибо за ответ. Он все еще запускает процесс через 5 минут. `kill: использование: kill [-s sigspec | -n Signum | -sigspec] pid | jobspec ... или kill -l [sigspec] `. Это дает мне эту строку после того, как каждый процесс занимает более 5 минут. и это все еще управляет этим, что не то, что я хочу. Hk148 9 лет назад 0
@ Hk148: Я получил это на работу, в несколько искусственном тесте. (Я получил сообщение `kill: (1234) - Нет такого сообщения процесса для каждого вызова, который завершился до истечения времени.) Вы уверены, что набираете его правильно? (Попробуйте скопировать и вставить.) Какую операционную систему вы используете? G-Man 9 лет назад 0
Недостатком этого метода является то, что вывод «процесс уничтожения» и «отсутствие такого процесса» имеют недостаток. Я попытался запустить его с `2> & 1> / dev / null` после команды kill, но он не пропустил вывод, поэтому для ясности я пропустил это в решении. Я тестировал его на Cygwin, а не на действительно UNIX-оболочке, но аргументы для таких команд, как `kill`, должны совпадать с большинством Linux-пакетов NuTTyX 9 лет назад 0
@ G-Man Я использую Mac OSX, но проблема в том, что через 5 минут он не запускает следующий тест или следующую строку. Через 5 минут он просто останавливает все. Hk148 9 лет назад 0
@NuTTyX есть ли другие способы сделать это в коде Java? Hk148 9 лет назад 0
Похоже, в Mac OS X есть bash 3.2, поэтому мое первое решение не сработает. Я включил новый. Попытайся. NuTTyX 9 лет назад 0
Просто предупреждение: при правильных условиях это решение может убить неправильный процесс. Если удаляемый процесс завершился, его PID может быть назначен другому процессу. А некоторые системы unix-y назначают PID псевдослучайно, поэтому PID может быть переработан раньше, чем вы ожидаете. Kenster 9 лет назад 0
@Kenster верно, но маловероятно для не очень загруженных серверов и в течение этого 5-минутного перерыва. Кроме того, это очень уродливо, так как печатает вывод "kill" каждый раз, но проще всего, поскольку вам не нужно редактировать код Java и полагаться на общие команды. Я включил новое решение, которое должно быть чище и безопаснее. NuTTyX 9 лет назад 0
1
G-Man

Если ваша система имеет timeoutкоманду, вы сможете использовать ее, как

timeout 300s java -jar IPM.jar 0 20 3 sign.txt ︙ 
`man timeout` или` info coreutils 'timeout invocation'` для получения полной помощи. Это часть _GNU coreutils_. Hastur 9 лет назад 0
@ G-Man Когда я пытаюсь это сделать, он говорит: `timeout: команда не найдена`. Я думаю, что эта версия не может найти тайм-аут или у меня его нет на моем Mac Hk148 9 лет назад 0
@ Hk148: Да, после того, как NuTTyX выяснил, что ваша версия bash слишком старая, чтобы поддерживать его первый ответ, я боялся, что в OS X это тоже будет не хватать. G-Man 9 лет назад 0