Конечный хвост-f запустился в сценарии оболочки

У меня есть следующее.

  1. Запись процесса Java регистрируется к stdout
  2. Сценарий оболочки, начинающий процесс Java
  3. Другой сценарий оболочки, который выполняет предыдущий и перенаправляет журнал
  4. Я проверяю файл журнала с tail -f команда для сообщения успеха.

Даже если у меня есть выход 0 в коде, я не могу закончить tail -f процесс.

Который не позволяет моему сценарию для окончания. Есть ли какой-либо другой способ сделать это в Bash?

Код похож на следующее.

function startServer() {
  touch logfile
  startJavaprocess > logfile &

  tail -f logfile | while read line 
  do
    if echo $line | grep -q 'Started'; then
      echo 'Server Started'
      exit 0
    fi
  done
}
26
задан Peter Mortensen 27 February 2011 в 13:38
поделиться

7 ответов

Используйте CSS. удаляет подчеркивания из a и u элементов:

a, u {
    text-decoration: none;
}

Иногда необходимо переопределить другие стили элементов, в этом случае можно использовать ! важный модификатор в правиле:

a {
    text-decoration: none !important;
}
-121--555912-
string ReadLine(int timeoutms)
{
    ReadLineDelegate d = Console.ReadLine;
    IAsyncResult result = d.BeginInvoke(null, null);
    result.AsyncWaitHandle.WaitOne(timeoutms);//timeout e.g. 15000 for 15 secs
    if (result.IsCompleted)
    {
        string resultstr = d.EndInvoke(result);
        Console.WriteLine("Read: " + resultstr);
        return resultstr;
    }
    else
    {
        Console.WriteLine("Timed out!");
        throw new TimedoutException("Timed Out!");
    }
}

delegate string ReadLineDelegate();
-121--683709-

Лучший ответ, который я могу найти, это

  1. Установите тайм-аут для чтения, tail -f logfile | read -t 30 line
  2. Начните с -pid = $ , таким образом он выйдет, когда bash-процесс

Он будет охватывать все случаи, о которых я могу думать (зависание сервера без вывода, выход сервера, запуск сервера корректно).

Не забудьте запустить хвостовую часть перед сервером.

tail -n0 -F logfile 2>/dev/null | while read -t 30 line

-F будет «читать» файл, даже если он не существует (начните чтение, когда он появится). -n0 не будет ничего читать в файле, поэтому вы можете продолжать добавлять файл журнала вместо того, чтобы перезаписывать его каждый раз, а также выполнять стандартное вращение журнала.

EDIT:
OK, поэтому довольно грубое «решение», если вы используете хвост. Возможно, есть лучшие решения, использующие что-то другое, кроме хвоста, но я должен дать его вам, хвост доставляет вас из пробитой трубы довольно красиво. «Тройник», который способен обрабатывать SIGPIPE, вероятно, будет работать лучше. Процесс Java, активно выполняющий сброс файловой системы с сообщением «im alive» какого-то рода, вероятно, еще проще дождаться.

function startServer() {
  touch logfile

  # 30 second timeout.
  sleep 30 &
  timerPid=$!

  tail -n0 -F --pid=$timerPid logfile | while read line 
  do
    if echo $line | grep -q 'Started'; then
      echo 'Server Started'
      # stop the timer..
      kill $timerPid
    fi
  done &

  startJavaprocess > logfile &

  # wait for the timer to expire (or be killed)
  wait %sleep
}
25
ответ дан 28 November 2019 в 07:12
поделиться

Как насчет использования бесконечного цикла вместо -f опции командной строки для tail?

function startServer() {
  startJavaprocess > logfile &

  while [ 1 ]
  do
   if tail logfile | grep -q 'Started'; then
    echo 'Server started'
    exit 0
   fi
  done
}
1
ответ дан 28 November 2019 в 07:12
поделиться

Не используйте хвост - вы можете получить тот же «монитор новой вещи в файле», используя READ .

Здесь я использую FIFO вместо файла журнала:

function startServer() {
  mkfifo logfile
  startJavaprocess > logfile &

  a=""; while [ "$a" != "Started" ]; do read <logfile a; done

  echo "Server Started"
}

Обратите внимание, что это оставляет висит FIFO вокруг.

0
ответ дан 28 November 2019 в 07:12
поделиться

Захват PID фонового процесса

pid=$!

Использование хвоста - PID = PID - PID = PID - PID = PID - PID = PID - PID = PID , так что он завершается после того, как процесс, имеющий PID $ PID.

2
ответ дан 28 November 2019 в 07:12
поделиться

Это должно сработать и хвост должен умереть, как только подоболочка умрет


function startServer() {
  touch logfile
  startJavaprocess > logfile &

  while read line 
  do
    if echo $line | grep -q 'Started'; then
      echo 'Server Started'
      exit 0
    fi
  done < <(tail -f logfile)
}

Попробуйте так:

function startServer() {
  while read line 
  do
    if echo $line | grep -q 'Started'; then
      echo 'Server Started'
      return 0
    fi
  done < <(startJavaprocess | tee logfile)
}
0
ответ дан 28 November 2019 в 07:12
поделиться

, а не выходя из процесса, вы можете вместо этого найти идентификатор процесса хвостового хвоста и убить его ( A Убить -9 даже было бы безопасно здесь, если вы уверены, что файл журнала закончен).

Таким образом, при чтении будет прекращена естественным путем, и вам не нужно выходить.

Или, поскольку вы на самом деле не используете хвост для вывода на экран, вы также можете попробовать более старую школу:

grep -q 'Started' logfile
while [[ $? -ne 0 ]] ; do
    sleep 1
    grep -q 'Started' logfile
done
1
ответ дан 28 November 2019 в 07:12
поделиться

Согласно странице страницы хвостового человека , вы можете получить хвост для завершения после того, как процесс умирает

в Bash, вы можете получить PID последнего начального фонового процесса, используя $! Так что, если вы используете Bash:

tail -f --pid=$! logfile
6
ответ дан 28 November 2019 в 07:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: