команда nohup tail с перенаправлением в сценарии оболочки не вызывается должным образом в конкретной ситуации

1116
Neha Sharma

У меня проблема, из-за которой команда tail в скрипте bash не работает правильно при вызове с удаленного компьютера, предоставляя только 1 параметр из 2. Но это работает правильно, если:

  • выполняется непосредственно на местном с 1 парам
  • выполняется непосредственно на местном с 2-мя параметрами
  • выполнено с пульта с 2 параметрами

Я написал ниже сценарий, который начинается с следующего. Требуется 2 параметра:

  1. TESTNAME: этот параметр является обязательным. Это название контрольного примера. Он создает файл журнала с этим именем.
  2. SLAVE_HOST: этот параметр является необязательным. Если он предоставлен, он будет подключаться к предоставленному подчиненному хосту и запускать на нем аналогичный сценарий.

    #!/bin/bash TESTNAME="$1"  testdate=$(date +'%m_%d_%Y') REG_DIR=/opt/reg-test-results/REG_"$testdate"  #create regression results directory if it does not exist mkdir -p "$REG_DIR"  FILENAME="$REG_DIR"/"$TESTNAME"  #if file already exists, create a new one with current time stamp appended to name if [ -f "$FILENAME" ]; then TIME=$(date +'%m_%d_%Y-%H.%M.%S') FILENAME="$FILENAME"_"$TIME" fi  echo "$FILENAME" > /opt/reg-test-results/currentTestName  #start tailing nohup tail -f -n0 /path/to/log/files/*/*server.log > "$FILENAME" & echo "$!" > $REG_DIR/reg_tail.pid  #if slave host is provided, start tailing logs on slave also if [ "$#" -gt 1 ]; then SLAVE_HOST="$2" ssh "$SLAVE_HOST" /path/to/script/startTailLogTestCaseSlave.sh "$FILENAME" fi 

Первые несколько строк кода сохраняют параметры в переменных, создают структуру каталогов и имя файла журнала, куда будут направлены хвостовые журналы. После этого у меня есть команда nohup tail, чтобы начать отслеживать журналы и направлять их в файл журнала. Это строка кода, которая не работает должным образом. Затем, если был предоставлен второй аргумент, он отправится на этот хост по ssh и выполнит на нем команду.

Проблема: при запуске из удаленного режима и передаче обоих параметров, я вижу, что после выполнения этого скрипта запускается хвостовой процесс, и я вижу, что файл журнала заполняется содержимым должным образом. Но если я предоставлю только первый параметр, то, похоже, он запускает tail и сразу останавливает его, потому что я вижу новый идентификатор процесса в файле reg_tail.pid, но файл журнала ($ FILENAME) не создается, и не выполняется ни один хвостовой процесс.

Сценарий отлично работает либо с 1 параметром, либо с обоими, когда выполняется непосредственно на машине.

Под «удаленным запуском» я подразумеваю ssh для машины и запускаю скрипт. Например:

$ ssh -t user@host /path/to/script/script.sh testcasename.log 

Отладка:

Вот что я вижу, когда использую set -x и запускаюсь с удаленного компьютера:

Когда передан второй аргумент и все работает нормально, я вижу, что nohup tail выполняется в самом конце.

 .... + echo 13441 + '[' 2 -gt 1 ']' + SLAVE_HOST=slaveHost + ssh slaveHost /path/to/script/startTailLogTestCaseSlave.sh /opt/reg-test- results/REG_09_11_2015/logs2.log + nohup tail -f -n0 /path/to/logs/../check-server.log ... nohup: redirecting stderr to stdout Connection to hostname closed. 

Когда передается только первый аргумент, nohup tail никогда не выполняется:

 ... + echo 13607 + '[' 1 -gt 1 ']' Connection to hostname closed. 
-2
(1) Вау. Вы вошли в систему на hostA, и вы набираете `ssh hostB scriptname filename hostC`, и * скрипт вызывает *` ssh hostC scriptname filename`? Вы можете сделать шаг назад и посмотреть, сможете ли вы упростить свой дизайн. (2) Скрипт показывает команду `tail` перед командой` ssh "$ SLAVE_HOST"… `- но ваш диагностический вывод` set -x` показывает `tail` после` ssh`. Хотите объяснить это? (3) Вы должны всегда заключать в кавычки переменные оболочки, если у вас нет веских причин не делать этого, и вы * уверены *, что знаете, что делаете. Scott 8 лет назад 0
Зачем вам здесь `nohup`? Я думаю, что в этом случае может возникнуть проблема с дескрипторами выходного файла. Breakthrough 8 лет назад 0
Всем спасибо. @ Скотт, отметил # 1. Благодарю. О # 2, это порядок, который я вижу. Я не знаю причину. Хвост всегда выполняется в конце, когда я передаю второй аргумент. Я пробовал много вариантов, таких как передача строки со значением «null» для SLAVE_HOST и добавил условие, чтобы не ssh к нему, если значение «null». Он запускает tail только при выполнении команды ssh и запускает tail после ssh, даже если команда tail предшествует ssh. О # 3, обновил мой код, чтобы всегда использовать кавычки. Neha Sharma 8 лет назад 0
@ Прорыв, удаление nohup не помогло. Neha Sharma 8 лет назад 0
@NehaSharma Почему вы добавили `nohup`? Объяснение может помочь отладить проблему здесь. При этом, если вы получаете такое же поведение без `nohup`, то это не имеет никакого отношения к вашей конкретной проблеме / вопросу в первую очередь. Breakthrough 8 лет назад 0
@Breakthrough, я добавил его, потому что когда я запускал его удаленно, иногда команда tail не работала, но иногда это было. Я не знал причину, но я только посмотрел на это и похоже, что ответ здесь: https://en.wikipedia.org/wiki/Nohup. Там также сказано: «Также обратите внимание, что закрывающий сеанс SSH не всегда посылает сигнал HUP. зависимым процессам Neha Sharma 8 лет назад 0
@NehaSharma Вы уверены, что команда не выполнена и вместо этого просто не отображается (например, после запуска сценария, даже если вы не видите строку `nohup tail ...`), это вывод в `$ FILENAME `там хотя бы)? Breakthrough 8 лет назад 0
@ Прорыв, да, я уверен. Я видел, что pid для tail, который мой сценарий записывал в reg_tail.pid, каждый раз печатал новый pid. Однако когда я искал процесс по pid или искал процесс tail -f, ни одного не было. Итак, какой-то процесс был создан и убит. Выходной файл $ FILENAME также не был создан. Neha Sharma 8 лет назад 0

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

0
Neha Sharma

I resolved the issue by adding a delay after tail command.

nohup tail -f -n0 /path/to/log/files/*/*server.log > "$FILENAME" 2> test.err < /dev/null & echo "$!" > "$REG_DIR"/reg_tail.pid #without this delay, the above tail command is not being executed when only one 1 argumet is passed sleep 1 #if slave host is provided, start tailing logs on slave also if [ "$#" -gt 1 ]; then 

I was wondering why it works after ssh command is executed even though it's unrelated. So, I decided to add a delay. Though I am no expert, but it looks like a race condition. The tail background process was being scheduled to run at the end and in the case where no ssh command was executed, the script exited and session ended before the tail process could get a chance to run. Putting main process to sleep gives a chance to tail process (or thread) to run. Given that, I am not sure that this solution is the best. If I use wait instead of sleep, it gets stuck because "tail -f" will keep running. I am using this script to tail logs and then run a test case. After test case execution completed, I am running another script which reads the pid of tail from where it is stored and kills tail. Please let me know if I am mistaken in my understanding and also if there is a better solution.

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