Рейтинг:0

Синтаксическая ошибка при использовании End of Message (EOM) внутри цикла while в сценарии оболочки Ubuntu

флаг in

У меня есть код, содержащий команду, в которой пользователю предлагается выбрать вариант из показанных в меню. Это нужно многократно выполнять несколько раз, поэтому я использовал цикл while. Теперь я использовал метод EOM (конец сообщения), чтобы ввести данные при появлении запроса. При использовании я заметил, что этот метод вызывает следующую ошибку при выполнении. Я сузил ошибку до этой части кода (строки 80–83) и не могу ее пройти.

Пожалуйста, помогите мне решить эту проблему.

Строки, в которых возникает ошибка:

ТЕМП="q"
gmx_mpi make_ndx -f pull_sim.gro -o index.ndx <<EOM
$TEMP
ЕОМ

Ошибка:

./Run_Pull_Code.sh: 105: Синтаксическая ошибка: неожиданный конец файла (ожидание «готово»)

Пожалуйста, найдите полный следующий код (см. строки с 80 по 83 здесь):

#!/бин/ш
# Комментарий выше устанавливает файл sh для выполнения в качестве интерпретатора (построчно)

# Находим текущий рабочий каталог
BASEDIR=$(pwd)
echo "Сейчас я нахожусь в следующем каталоге:"
эхо "$BASEDIR"
эхо " "


################################################### #########################################
# Установка позиций и декрементов кода вытягивания (Все в нм)
################################################### #########################################
DECREMENT=0,5 # Шаги в нм
RANGE=1 #От самой высокой до самой низкой позиции
MID_POS=9.327 # Наблюдение за высшей молекулой воды (атомом O) на поверхности воды
INIT_POS=$( echo "$MID_POS + $RANGE" | bc -l) # Начальная позиция
LAST_POS=$( echo "$MID_POS - $RANGE" | bc -l) # Конечная позиция
CURR_POS=$INIT_POS # Назначение исходной позиции текущей позицией


LOOP_CNT=0
в то время как [ 1 -eq "$(echo "${LAST_POS} <= ${CURR_POS}" | bc)" ]
делать 
    # увеличить значение
    LOOP_CNT=$(эхо "$LOOP_CNT + 1" | bc -l)
    РАССТОЯНИЕ=$CURR_POS

    # Установка номера цикла (X) в качестве номера кода извлечения для симуляции (X)
    SIM_CNT=$LOOP_CNT

    # Создание каталогов (1) X_Pull (2) X_Pull/Making
    DIR_NAME_MAIN=$SIM_CNT"_Pull"
    mkdir $DIR_NAME_MAIN
    DIR_NAME_MAKING=$SIM_CNT"_Вытягивание/Изготовление"
    mkdir $DIR_NAME_MAKING
    
    эхо " "
    echo "Я создал каталоги."
    эхо " "

    # Копирование файлов из папки предварительных условий во вновь созданную папку
    cp Предварительные требования/Avo_decanol.pdb Предварительные требования/water_box.pdb $DIR_NAME_MAKING
    cp Prerequisites/simulation_file.mdp Prerequisites/topol.top $DIR_NAME_MAIN
    
    ################################################### #########################################
    # Делаем симуляционную коробку "pull_sim.gro"
    ################################################### #########################################
    компакт-диск $DIR_NAME_MAKING
    #(1) Зафиксируйте расстояние деканола от поверхности воды и сделайте единственную деканоловую коробку с такими же размерами, как и у водяной коробки.
    РАССТОЯНИЕ=9,5 
    gmx_mpi editconf -f Avo_decanol.pdb -o Dec_box.pdb -center 2.5 2.5 $DISTANCE -box 5 5 12
    #(2) СОЗДАНИЕ CONSTANT HEADER И ENDER cat файлов в формате PDB
    # Первые 4 строки любого файла PDB содержат информацию о размере коробки, имени и т. д.
    # Просто скопируйте четыре строки в отдельный файл HEADER PDB с помощью следующей команды.
    sed -n '1,4p' Dec_box.pdb > HEADER.pdb
    #Последние 2 строки также являются общими для всех файлов PDB, поэтому скопируйте их в файл ENDER PDB с помощью следующей команды.
    sed -n '38,39p' Dec_box.pdb > ENDER.pdb
    #(3) Отделите свойства атома деканола от его PDB-файла (строки с 5 по 37) с помощью следующей команды
    sed -n '5,37p' Dec_box.pdb > file_1.pdb
    #(4) Отделите свойства атома воды от его файла PDB (строка 5 до 15004) с помощью следующей команды
    sed -n '5,15004p' water_box.pdb > file_2.pdb
    #(5) Теперь соедините все вышеперечисленные файлы с PDB-файлом водной поверхности в следующей последовательности:
    cat HEADER.pdb file_1.pdb file_2.pdb ENDER.pdb > pull_sim.pdb
    #(6) Переставить все количество атомов в файле pull_sim.pdb и преобразовать его в файл GRO, файл pull_sim.gro.
    gmx_mpi editconf -f pull_sim.pdb -o pull_sim.gro -center 2.5 2.5 6.0 -box 5.0 5.0 12.0 -resnr 1

    # Копируем недавно созданный файл pull_sim.gro из папки make в предыдущую папку
    CD ../
    cp Изготовление/pull_sim.gro ./
        
    эхо " "
    echo "Пуллбокс создан."
    эхо " "
    
    ################################################### #########################################
    # Запускаем симуляцию
    ################################################### #########################################
    # (1) Создание индексного файла
    ТЕМП="q"
    gmx_mpi make_ndx -f pull_sim.gro -o index.ndx <<EOM
    $TEMP
    ЕОМ
    # (2) Создание файла tpr из модуля grompp
    gmx_mpi grompp -f файл_симуляции.mdp -p topol.top -c pull_sim.gro -n index.ndx -maxwarn 0 -o nvt.tpr
    # Очистка всего содержимого
    чистый
    эхо " "
    echo "#####################************ Моделирование вытягивания: $LOOP_CNT *********** ######################"
    эхо " "
    # (3) мдрун
    gmx_mpi mdrun -v -deffnm nvt -nb gpu -pme gpu -pmefft gpu -bonded gpu
        
    # Возврат в основную папку
    CD ../
    
    # Уменьшение расстояния для следующего цикла
    CURR_POS=$( эхо "$CURR_POS - $DECREMENT" | bc -l)
сделано
    
#чистый
эхо " "
эхо "Завершено"
эхо " "
terdon avatar
флаг cn
В чем ошибка? И какой ввод ожидает эта команда `gmx_mpi make_ndx`? Как бы вы его запустили, если бы не использовали heredocs (EOM)? Не могли бы вы передать ему файл? Строка?
terdon avatar
флаг cn
И несколько общих комментариев: i) избегайте использования CAPS для имен переменных в сценариях оболочки. По соглашению глобальные переменные среды пишутся с заглавной буквы, поэтому наличие ваших собственных переменных в заглавных буквах может привести к конфликтам имен переменных, которые очень сложно отлаживать. Обычно рекомендуется избегать заглавных букв в сценариях оболочки. ii) ***всегда двойные кавычки ваших переменных***. См. [Последствия для безопасности, если вы забыли указать переменную в кавычках в оболочках bash/POSIX] (https://unix.stackexchange.com/q/171346). iii) вы можете увеличить переменную изначально в оболочке, нет необходимости в `bc`: `let LOOP_CNT++` или `((LOOP_CNT++))`.
флаг in
Спасибо за совет. Теперь я отредактировал и упомянул об ошибке. Пожалуйста, посмотрите.
Рейтинг:2
флаг cn

Heredocs не могут иметь отступ, как остальная часть скрипта (если только вы не используете -ЕОМ но тогда вы можете делать отступы только с помощью табуляции). В конце концов, цель heredoc — позволить вам написать что-то, что появится как есть. Это означает, что ЕОМ не может быть так:

пока что-то; 
делать
    команда <<ЕОМ
    Привет!
    ЕОМ
сделано  

Вместо этого ЕОМ (или любой другой пометкой, которую вы используете) должен быть единственным элементом в строке, поэтому не должно быть пробелов или чего-либо еще до или после него. Как это:

пока что-то; 
делать
    команда <<ЕОМ
    Привет!
ЕОМ
сделано  

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

с=0;
в то время как [ $c -eq 0 ]; 
делать
    кот <<ЕОМ
    Привет!
ЕОМ
    пусть С++
сделано  

Будет печатать:

$ foo.sh
    Привет!

Пока это:

с=0;
в то время как [ $c -eq 0 ]; 
делать
    кот <<ЕОМ
Привет!
ЕОМ
    пусть С++
сделано  

Будет печатать:

$ foo.sh
Привет!

Наконец, при запуске вашего скрипта я получаю другую ошибку:

$ foo.sh
В настоящее время я нахожусь в следующем каталоге:
/дом/тердон/фу
 
/home/terdon/scripts/foo.sh: строка 108: предупреждение: здесь-документ в строке 84 разделен концом файла (требуется `EOM')
/home/terdon/scripts/foo.sh: строка 109: синтаксическая ошибка: неожиданный конец файла

Это произойдет потому, что я не предоставляю одни и те же входные данные, и, поскольку вы неправильно завершили EOM, ваши данные, вероятно, обрабатывались сценарием, и поэтому вы увидели другую ошибку. Я ожидаю, что мое исправление избавится от этого, поскольку оно позволило мне запустить ваш скрипт до конца на моей машине.

muru avatar
флаг us
Heredocs могут иметь отступ, когда вы используете начальный дефис перед словом-разделителем (например, `
terdon avatar
флаг cn
@muru правда, я никогда этого не помню, я просто не делаю отступов и останавливаюсь на этом. Но хороший момент, спасибо.
флаг in
Большое спасибо, сэр. Теперь моя проблема решена.

Ответить или комментировать

Большинство людей не понимают, что склонность к познанию нового открывает путь к обучению и улучшает межличностные связи. В исследованиях Элисон, например, хотя люди могли точно вспомнить, сколько вопросов было задано в их разговорах, они не чувствовали интуитивно связи между вопросами и симпатиями. В четырех исследованиях, в которых участники сами участвовали в разговорах или читали стенограммы чужих разговоров, люди, как правило, не осознавали, что задаваемый вопрос повлияет — или повлиял — на уровень дружбы между собеседниками.