-2

У меня проблема, из-за которой команда 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.

1 ответ1

0

Я решил проблему, добавив задержку после хвостовой команды.

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

Мне было интересно, почему это работает после выполнения команды ssh, даже если она не связана. Итак, я решил добавить задержку. Хотя я не эксперт, но это похоже на состояние гонки. Конечный фоновый процесс планировалось запустить в конце, и в случае, если команда ssh не была выполнена, сценарий завершился, и сеанс завершился, прежде чем хвостовой процесс смог получить возможность запуска. Перевод основного процесса в спящий режим дает возможность запустить процесс (или поток). Учитывая это, я не уверен, что это решение является лучшим. Если я использую wait вместо sleep, он застревает, потому что tail -f будет продолжать работать. Я использую этот сценарий для привязки логов, а затем запускаю контрольный пример. После завершения выполнения тестового сценария я запускаю другой скрипт, который считывает pid tail, из которого он хранится, и уничтожает tail. Пожалуйста, дайте мне знать, если я ошибаюсь в моем понимании, а также, если есть лучшее решение.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .